Read the session record strictly, and make its tests hold (hq ADR 0272)
- UID, CLASS and SCOPE are read at their first occurrence: logind writes
each once, and a later line saying otherwise is not the record's word.
- A comment says /run/systemd/sessions is systemd's private format, and
that a format change fails closed: no session, so nobody is the terminal.
- Tests that hold, each proved by the mutation it guards failing:
- a record naming UID=1001 for session-8.scope under user-1000.slice,
asked as uid 1000 (the record's UID check alone);
- session-a.b.scope with a passing record (the id's characters alone);
- session-9.scope/x.scope (the scope being the slice's direct child);
- a key said twice, either way round (first occurrence);
- the client sends its line only after the session was read, so reading
the session in the forward fails the test.
This commit is contained in:
@@ -116,9 +116,17 @@ func userSessionIn(cgroup string, uid uint32) string {
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
// **The record is systemd's private format**, not an interface it promises: `KEY=value` lines logind writes for
|
||||
// itself. Only UID, CLASS and SCOPE are read, each at its first occurrence — logind writes each once, and a later
|
||||
// line saying otherwise is not the record's word. A systemd that changes the format, renames a key or stops
|
||||
// writing the file fails closed here: no session is read, so nobody is the terminal until this reads it again.
|
||||
record := map[string]string{}
|
||||
for _, line := range strings.Split(string(raw), "\n") {
|
||||
if k, v, ok := strings.Cut(line, "="); ok {
|
||||
k, v, ok := strings.Cut(line, "=")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if _, said := record[k]; !said {
|
||||
record[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user