4

We have a strange problem in Solaris 11.4.

The problem arise when a code as the following is run from Perl

my $emptystring = "";
syswrite STDOUT, $emptystring;

The execution of a syswrite call with an empty variable provoques that the OpenSSH session is killed :-(

The problem is new for us, and it's arise after the migration from Solaris 11.3 to Solaris 11.4 and with OpenSSH 8.1 (with previous 7.9 version the problem is not there)

This error occurs only if the output is the standard output. If the output of the script is redirected to a file everything works ok

If the script is traced with truss the error occurs in a write call like this one:

23886:  write(1, 0x004B6450, 0)             = 0

The write call shown is for when everything is ok, when the error arises the session is killed and the truss output is stopped et this line and everything after is not shown.


More info: We have tested binaries compiled for Solaris 11.3 and they work!. So apparently the problem comes from our compilation, but we don't know yet why .... On continue ...


More info: There is no remarkable difference between la compilation. The logs of the server OpenSSH show that the empty value is taken as an EOF, as we can see in the following image, that show the difference between a OpenSSH with this bug and another one which behaves correctly.

enter image description here

The lines showing it are the following:

debug2: channel 0: read<=0 rfd 16 len 0
debug2: channel 0: read failed
debug2: channel 0: chan_shutdown_read (i0 o0 sock -1 wfd 16 efd -1 [closed])
debug2: channel 0: input open -> drain
debug2: channel 0: ibuf empty
debug2: channel 0: send eof
debug3: send packet: type 96
debug2: channel 0: input drain -> closed

Any idea?

6
  • What version of perl do those system have? I vaguely remember a similar bug, but it was long time ago. Oct 20 '20 at 19:47
  • 1
    The bug being that perl was not actually calling write(2) with an empty string, but with some garbage, because of an off-by-one bug. It would help if you used truss or similar to see what it's actually happening. Oct 20 '20 at 19:56
  • The Perl version is 5.16. What is strange here is that the error does not occurs with OpenSSH 7.9 and with Solaris 11.3. If I made truss i can see that error is exactly in the write call. When it does not fails the write call is like write(1, 0x004B6450, 0) = 0, when it fails the write is not even shown in the truss command output.
    – Ciges
    Oct 21 '20 at 13:02
  • This error occurs only if the output is the standard output. If the output of the script is redirected to a file everything works ok.
    – Ciges
    Oct 21 '20 at 13:07
  • As a guess: write() with length 0 to slave pty causes read() with length 0 at master pty (where sshd reads data for client), so, sshd considers this as EOF and so closed terminal session. You may check this by running sshd under truss/analog.
    – Netch
    Oct 22 '20 at 20:53
1

Solution found! :-) In short, we have to set the C flag PTY_ZEROREAD in the configure phase of the compilation.

In the channels.c file of te source code we can see where the error is thrown ...

#ifndef PTY_ZEROREAD
    if (len <= 0) {
#else
    if ((!c->isatty && len <= 0) ||
        (c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
#endif
        debug2("channel %d: read<=0 rfd %d len %zd",
            c->self, c->rfd, len);
        if (c->type != SSH_CHANNEL_OPEN) {
            debug2("channel %d: not open", c->self);
            chan_mark_dead(ssh, c);
            return -1;
        } else {
            chan_read_failed(ssh, c);
        }
        return -1;
    }

And we can see that the compilation flag PTY_ZEROREAD changes how the zero length messages are treated in terminals.

To solve the problem the configure command has to be done with the C flag set as shown in the last line of the following command:

./configure --with-zlib           \
        --with-pam                \
        --with-md5-passwords      \
        CFLAGS="-DPTY_ZEROREAD=1"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.