Why
internal/std/user/user.shellf:56:
observe { return state(member: shell { id -nG "$user" | tr ' ' '\n' | grep -qx "$group" }.exit == 0) }
grep -qx without -F: the group name is a basic regular expression, not a literal.
Debian allows . and - in a group name (NAME_REGEX in adduser.conf), so a request for
group a.b is satisfied by membership of axb, and the def reports already over a user who
is not in the group asked for.
Exactly the class of #594/#598, fixed then in htpasswd.entry — where the login was matched
with grep "^$user:" and a.b read another account's hash. The same shape survived here.
Low severity: it needs a group whose name carries a regex metacharacter and a
similarly-shaped group the user is already in. It is a one-token fix, and #535 settled that a
hostile argument is ordinary input, so the inconsistency is the thing to correct rather than
the risk.
Build
grep -qxF -- "$group". -- as well: a group name starting with a dash is otherwise read as
options — the same defect as #639, in a def written before it.
Check the rest of user.shellf and the neighbouring defs for the same call shape while there;
htpasswd.entry and postgres.hba already use the literal form, so the fix is to match what
the tree mostly does.
Validation
- An adverse case: create groups
axb and a.b, put the user in axb only, call
user.group(user, "a.b"), then assert on the machine that the user is in a.b.
Verified red before the fix.
- The case must build a state the def calls converged (
test/e2e/adverse-cases.md), or
the apply runs anyway and the assertion cannot fail.
coverage.shellf's existing call still converges on a second run.
Why
internal/std/user/user.shellf:56:grep -qxwithout-F: the group name is a basic regular expression, not a literal.Debian allows
.and-in a group name (NAME_REGEXinadduser.conf), so a request forgroup
a.bis satisfied by membership ofaxb, and the def reportsalreadyover a user whois not in the group asked for.
Exactly the class of #594/#598, fixed then in
htpasswd.entry— where the login was matchedwith
grep "^$user:"anda.bread another account's hash. The same shape survived here.Low severity: it needs a group whose name carries a regex metacharacter and a
similarly-shaped group the user is already in. It is a one-token fix, and #535 settled that a
hostile argument is ordinary input, so the inconsistency is the thing to correct rather than
the risk.
Build
grep -qxF -- "$group".--as well: a group name starting with a dash is otherwise read asoptions — the same defect as #639, in a def written before it.
Check the rest of
user.shellfand the neighbouring defs for the same call shape while there;htpasswd.entryandpostgres.hbaalready use the literal form, so the fix is to match whatthe tree mostly does.
Validation
axbanda.b, put the user inaxbonly, calluser.group(user, "a.b"), then assert on the machine that the user is ina.b.Verified red before the fix.
test/e2e/adverse-cases.md), orthe apply runs anyway and the assertion cannot fail.
coverage.shellf's existing call still converges on a second run.