GNU/Linux >> Tutoriales Linux >  >> Linux

¿La sesión de Openssh se cancela cuando desde Perl se realiza una llamada Syswrite con una variable vacía en Solaris 11?

Tenemos un problema extraño en Solaris 11.4.

El problema surge cuando se ejecuta un código como el siguiente desde Perl

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

La ejecución de una llamada syswrite con una variable vacía provoca que la sesión de OpenSSH se elimine 🙁

El problema es nuevo para nosotros, y surge tras la migración de Solaris 11.3 a Solaris 11.4 y con OpenSSH 8.1 (con la versión anterior 7.9 el problema no está)

Este error ocurre solo si la salida es la salida estándar . Si la salida del script se redirige a un archivo, todo funciona bien

Si el script se rastrea con truss el error ocurre en un write llamada como esta:

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

La llamada de escritura que se muestra es para cuando todo está bien, cuando surge el error, la sesión se cancela y la salida de truss se detiene en esta línea y todo lo que sigue no se muestra.

Más información: Hemos probado binarios compilados para Solaris 11.3 y ¡funcionan!. Entonces, aparentemente, el problema proviene de nuestra compilación, pero aún no sabemos por qué … Al continuar…

Más información: No hay una diferencia notable entre la compilación. Los logs del servidor OpenSSH mostrar que el valor vacío se toma como un EOF , como podemos ver en la siguiente imagen, que muestran la diferencia entre un OpenSSH con este bug y otro que se comporta correctamente.

Las líneas que lo muestran son las siguientes:

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

¿Alguna idea?

Respuesta aceptada:

¡Solución encontrada! 🙂 En resumen, tenemos que establecer la bandera C PTY_ZEROREAD en la fase de configuración de la compilación .

En channels.c archivo del código fuente podemos ver donde se arroja el error …

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

Y podemos ver que el indicador de compilación PTY_ZEROREAD cambia cómo se tratan los mensajes de longitud cero en las terminales.

Relacionado:Linux:¿por qué la sesión ssh finaliza inmediatamente?

Para resolver el problema, configure El comando debe realizarse con el indicador C configurado como se muestra en la última línea del siguiente comando:

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

Linux
  1. ¿Cómo crear una máquina virtual desde cero con Virsh?

  2. llamar a una función cuando el programa haya terminado con ctrl c

  3. Definición de una variable con o sin exportación

  4. ¿Cómo hacer una solicitud/llamada HTTP con la carga JSON desde la línea de comandos?

  5. Llame al script de Python desde bash con argumento

Imprima desde cualquier lugar con CUPS en Linux

Primeros pasos con Tmux

Cancelar una llamada al sistema con ptrace()

Shell script cambia de directorio con variable

¿Cuándo se elimina un archivo creado con mkstemp()?

Crear un nuevo árbol de directorios vacío a partir de un árbol existente con archivos