GNU/Linux >> Linux Esercitazione >  >> Linux

La sessione Openssh viene interrotta quando da Perl viene effettuata una chiamata Syswrite con una variabile vuota in Solaris 11?

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.

Correlati:Linux – Perché la sessione ssh termina immediatamente?

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"

Linux
  1. `$xauthority` appare da 'nowhere' su Su+tmux?

  2. Screenshot di X da Tty?

  3. Alias ​​con variabile in bash

  4. Qual è il modo corretto per chiudere la mia applicazione PyQt quando viene uccisa dalla console (Ctrl-C)?

  5. Annulla una chiamata di sistema con ptrace()

Registra la tua sessione terminale con Asciinema

Stampa da qualsiasi luogo con CUPS su Linux

Iniziare con Tmux

Come eseguire la richiesta/chiamata HTTP con il payload JSON dalla riga di comando?

Chiama una funzione C dal codice C++

Come faccio a stampare systemctl a colori quando interagisco con un non-tty?