Read the session record strictly, and make its tests hold (hq ADR 0272)
mesh/merge-gate pass: builds mesh-host → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered

- 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:
jochen
2026-10-09 14:05:53 +02:00
parent 512b0edb02
commit b1e7b6d26e
2 changed files with 54 additions and 12 deletions
+9 -1
View File
@@ -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
}
}