Abbiamo uno strano problema in Solaris 11.4.
Il problema sorge quando un codice come il seguente viene eseguito da Perl
my $emptystring = "";
syswrite STDOUT, $emptystring;
L'esecuzione di una chiamata syswrite con una variabile vuota provoca l'interruzione della sessione OpenSSH 🙁
Il problema è nuovo per noi ed è sorto dopo la migrazione da Solaris 11.3 a Solaris 11.4 e con OpenSSH 8.1 (con la precedente versione 7.9 il problema non c'è)
Questo errore si verifica solo se l'output è l'output standard . Se l'output dello script viene reindirizzato a un file, tutto funziona correttamente
Se lo script è tracciato con truss
l'errore si verifica in una write
chiama così:
23886: write(1, 0x004B6450, 0) = 0
La chiamata di scrittura mostrata è per quando tutto è a posto, quando si verifica l'errore la sessione viene uccisa e l'output del truss viene interrotto su questa riga e tutto ciò che segue non viene mostrato.
Maggiori informazioni: Abbiamo testato i binari compilati per Solaris 11.3 e funzionano!. Quindi a quanto pare il problema viene dalla nostra compilation, ma non sappiamo ancora perché…. Avanti...
Maggiori informazioni: Non c'è alcuna differenza notevole tra la compilation. I log del server OpenSSH mostra che il valore vuoto viene preso come EOF , come possiamo vedere nell'immagine seguente, che mostrano la differenza tra un OpenSSH con questo bug e un altro che si comporta correttamente.
Le righe che lo mostrano sono le seguenti:
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
Qualche idea?
Risposta accettata:
Soluzione trovata! 🙂 In breve, dobbiamo impostare il flag C PTY_ZEROREAD
in fase di configurazione della compilazione .
In channels.c
file del codice sorgente possiamo vedere dove viene generato l'errore ...
#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;
}
E possiamo vedere che il flag di compilazione PTY_ZEROREAD
cambia il modo in cui i messaggi di lunghezza zero vengono trattati nei terminali.
Per risolvere il problema il configure
il comando deve essere eseguito con il flag C impostato come mostrato nell'ultima riga del comando seguente:
./configure --with-zlib \
--with-pam \
--with-md5-passwords \
CFLAGS="-DPTY_ZEROREAD=1"