GNU/Linux >> Znalost Linux >  >> Linux

Session Openssh je zabita, když se z Perlu uskuteční volání Syswrite s prázdnou proměnnou v Solaris 11?

V Solarisu 11.4 máme zvláštní problém.

Problém nastává, když je z Perlu spouštěn následující kód

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

Provedení volání syswrite s prázdnou proměnnou vyvolá, že relace OpenSSH je ukončena 🙁

Problém je pro nás nový a nastal po migraci ze Solaris 11.3 na Solaris 11.4 a OpenSSH 8.1 (u předchozí verze 7.9 problém není)

K této chybě dochází pouze v případě, že výstup je standardní výstup . Pokud je výstup skriptu přesměrován do souboru, vše funguje v pořádku

Pokud je skript trasován pomocí truss k chybě dochází při write volejte takto:

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

Zobrazené volání zápisu je pro případy, kdy je vše v pořádku, když dojde k chybě, relace je ukončena a výstup krovu je zastaven a na tomto řádku se nezobrazuje vše, co následuje.

Další informace: Testovali jsme binární soubory zkompilované pro Solaris 11.3 a fungují!. Problém tedy zřejmě pochází z naší kompilace, ale zatím nevíme proč…. Pokračovat…

Další informace: Mezi la kompilací není žádný významný rozdíl. Protokoly serveru OpenSSH ukazují, že prázdná hodnota je brána jako EOF , jak můžeme vidět na následujícím obrázku, které ukazují rozdíl mezi OpenSSH s touto chybou a jiným, který se chová správně.

Řádky zobrazující to jsou následující:

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

Nějaký nápad?

Přijatá odpověď:

Řešení nalezeno! 🙂 Stručně řečeno, musíme nastavit příznak C PTY_ZEROREAD ve fázi konfigurace kompilace .

V channels.c souboru zdrojového kódu můžeme vidět, kde je vyvolána chyba …

#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;
    }

A můžeme vidět, že příznak kompilace PTY_ZEROREAD změní způsob zacházení se zprávami s nulovou délkou v terminálech.

Související:Linux – Proč se relace ssh okamžitě ukončí?

Chcete-li problém vyřešit, configure příkaz musí být proveden s nastaveným příznakem C, jak je znázorněno na posledním řádku následujícího příkazu:

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

Linux
  1. `$xauthority` se na Su+tmux objevuje „odnikud“?

  2. zavolejte funkci po dokončení programu pomocí ctrl c

  3. Definování proměnné s exportem nebo bez exportu

  1. Jak provést HTTP-request/call s JSON payloadem z příkazového řádku?

  2. Zavolejte skript Python z bash s argumentem

  3. Volání funkce C z kódu C++

  1. Snímek obrazovky X From Tty?

  2. Když je smazán soubor vytvořený pomocí mkstemp()?

  3. Vytvořte nový prázdný adresářový strom z existujícího stromu se soubory