[Bug 4013] New: StreamLocalBindMask is applied from non-matching Host and Match blocks, and the last value wins
bugzilla-daemon at mindrot.org
bugzilla-daemon at mindrot.org
Sat Oct 3 06:45:57 AEST 2026
https://bugzilla.mindrot.org/show_bug.cgi?id=4013
Bug ID: 4013
Summary: StreamLocalBindMask is applied from non-matching Host
and Match blocks, and the last value wins
Product: Portable OpenSSH
Version: 10.5p1
Hardware: Other
OS: Linux
Status: NEW
Severity: major
Priority: P5
Component: ssh
Assignee: unassigned-bugs at mindrot.org
Reporter: jirenthegray03 at gmail.com
The mask is the umask used when the client creates a listening
Unix-domain socket for -L/-R (channels.c, around omask =
umask(fwd_opts->streamlocal_bind_mask)), so it decides who on the local
machine may use the forwarded channel. A mask written for one host is
applied to every host, which can both widen and narrow those
permissions with no diagnostic. sshd guards the same option correctly,
so the client's behaviour is also inconsistent with the server's.
Two defects in one handler: the Host/Match scope is ignored, and
precedence is reversed (every other client option keeps the first
value; this one keeps the last).
Reproduction:
```
# A mask set only for a host we are not connecting to. Expected: the
default 0177.
printf 'Host other\n StreamLocalBindMask 0077\n' > c
ssh -G -F c example.com | grep -i streamlocalbindmask # ->
streamlocalbindmask 077
printf 'Match host other\n StreamLocalBindMask 0077\n' > c
ssh -G -F c example.com | grep -i streamlocalbindmask # ->
streamlocalbindmask 077
# Precedence. Expected: the first value, 077.
printf 'StreamLocalBindMask 0077\nStreamLocalBindMask 0022\n' > c
ssh -G -F c example.com | grep -i streamlocalbindmask # ->
streamlocalbindmask 022
# Control, the same two shapes with Port: correctly 22 (default) and 11
(the first).
printf 'Host other\n Port 11\n' > c; ssh -G -F c example.com | grep
-iE '^port' # -> port 22
printf 'Port 11\nPort 22\n' > c; ssh -G -F c example.com | grep -iE
'^port' # -> port 11
```
Potential Cause: In readconf.c, case oStreamLocalBindMask: ends with an
unconditional options->fwd_opts.streamlocal_bind_mask = (mode_t)value;.
It tests neither *activep (which is why a non-matching block applies)
nor whether the field is still the (mode_t)-1 sentinel that
fill_default_options() turns into 0177 (which is why the last value
wins).
Potential Fix: Guard it the way servconf.c's case sStreamLocalBindMask:
already does, and add the first-wins test the neighbouring client
options use: if (*activep && options->fwd_opts.streamlocal_bind_mask ==
(mode_t)-1).
--
You are receiving this mail because:
You are watching the assignee of the bug.
More information about the openssh-bugs
mailing list