ssh client is setting O_NONBLOCK on a pipe shared with other processes

Doug Graham edougra at gmail.com
Tue Sep 17 09:41:22 AEST 2019


> Dumb question: shouldn't whatever is calling fork() (here 'make' I believe)
> be dup()'ing the FDs just in case the called program does something odd
> with them like set O_NONBLOCK?

Doesn't work.  That's where I think POSIX is downright weird.  Ssh
actually does dup
descriptors 0, 1, and 2, and then only sets O_NONBLOCK on the new descriptors:

        if (stdin_null_flag) {
                in = open(_PATH_DEVNULL, O_RDONLY);
        } else {
                in = dup(STDIN_FILENO);
        }
        out = dup(STDOUT_FILENO);
        err = dup(STDERR_FILENO);

        /* enable nonblocking unless tty */
        if (!isatty(in))
                set_nonblock(in);
        if (!isatty(out))
                set_nonblock(out);
        if (!isatty(err))
                set_nonblock(err);

The problem, I've learned, it that the original descriptor and the new
copy of it refer to the same
POSIX "file description", so setting O_NONBLOCK on one affects the
other as well.  I find this
quite counter-intuitive and it's why I'm starting to believe that the
bug is in POSIX.  I also
find it odd a child process can affect this flag in the parent, but
that again is because both the
parent and child's descriptors refer to the same POSIX "file description".


More information about the openssh-unix-dev mailing list