Exposed sshd -- looping sshd-auth
Havard Eidnes
he at uninett.no
Tue Oct 6 04:21:36 AEDT 2026
Hi again,
it turns out Theo was correct in pointing out the rather
confusing shenanigans done to read() when "stack smash
protection" is turned on in NetBSD.
The reason that one becomes problematic is that each compute unit
(each file, basically) gets its own "static inline" version of
read(), and then of course another file's read() isn't equal to
atomicio.c's version of read(), resulting in the earlier observed
behaviour.
The list of functions which get the "buffer overflow protection"
/ "stack smash protection" is listed in the ssp(3) man page, and
among them are the functions which handle externally-supplied
data, and read() is among them.
But write() is not among them (and by extension, neither is
vwrite()). So this makes for a relatively simple fix to portably
avoid the issue: in atomicio.c which now does
/*
* ensure all of data on socket comes through. f==read || f==vwrite
*/
size_t
atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
int (*cb)(void *, size_t), void *cb_arg)
{
...
pfd.events = f == read ? POLLIN : POLLOUT;
...
instead do
pfd.events = f != vwrite ? POLLIN : POLLOUT;
and that should be a portable fix, and would also help anyone
else which do SSP / FORTIFY. Or if you prefer the "positive"
test:
pfd.events = f == vwrite ? POLLOUT : POLLIN;
Evidently SSP is done slightly differently in NetBSD 11.x (using
"extern inline" instead of "static inline" in the SSP macros), so
that this problem doesn't occur there, but of course that does
nothing for the many NetBSD 10.x or older (admittedly no longer
"supported") systems out there.
So ... do with as you wish; I have a draft diff to the pkgsrc
package lined up along the lines above already, so I'm good as is.
Best regards,
- Havard
More information about the openssh-unix-dev
mailing list