Error de formato execvp exec para script de shell en Red Hat Enterprise Linux 6

Error de formato execvp exec para script de shell en Red Hat Enterprise Linux 6

Tenemos dos sistemas RHEL 6 que ejecutan versiones idénticas del kernel y glibc (glibc–2.12–1.90.el6_3.6). Según el estándar POSIX y las páginas de manual de Linux, si el kernel determina que un archivo ejecutable no está en un formato ejecutable como ELF y no tiene una #!línea shebang (), las funciones execl, execlp, execle, execv, execvpy execvpe(pero not execve) intentará ejecutar ese archivo usando un shell POSIX, que en Linux es /bin/sh.

Sin embargo, en uno de los sistemas, falla la ejecución de un script de shell cuya primera línea usa :la función execvp, mientras que en la otra máquina el script se ejecuta usando /bin/sh, como se esperaba. Específicamente, estamos usando estos programas de prueba; /tmp/test_scriptse hace ejecutable:

xc:

#incluir <stdio.h>
#incluir <unistd.h>
#incluir <stdlib.h>

carácter externo **entorno;

int principal () {
        char *argv[] = { "/tmp/test_script", NULL };
        char *nombre de programa = argv[0];
        if (execvp(nombre de programa, argv) == -1) {
                perror("execvp");
                devolver -1;
        }
}

/tmp/test_script:

:

echo "Secuencia de comandos de prueba llamada"
salir 0

Hemos buscado en el RPM de origen la versión instalada de glibc y definitivamente implementa el comportamiento deseado (execvp es un contenedor trivial de execvpe):

posix/execvpe.c:

si (strchr(archivo, '/') != NULL)
    {
        /* No buscar cuando contiene una barra. */
        __execve(archivo, argv, envp);

        si (errno == ENOEXEC)
            {
                /* Cuente los argumentos. */
                intarg = 0;
                mientras (argv[argc++])
                    ;
                size_t len ​​= (argc + 1) * sizeof(char *);
                char **script_argv;
                vacío *ptr = NULL;
                si (__libc_use_alloca(len))
                    script_argv = alloca(len);
                demás
                    script_argv = ptr = malloc(len);

                si (script_argv! = NULL)
                    {
                        scripts_argv(archivo, argv, argc, script_argv);
                        __execve(script_argv[0], script_argv, envp);

                        libre(ptr);
                    }
            }
    }
demás
   ︙

Aquí scripts_argvhay una función simple que se antepone /bin/sha la lista de argumentos y __execvees idéntica a la execveque se expone al espacio de usuario a través de glibc.

¿Alguien más ha encontrado este problema en Linux? El comportamiento es correcto en todos los demás sistemas en los que lo he probado.

Respuesta1

Muy bien, descubrí cómo llamaba el problema. Después de compilar el x.cejecutable, lddlo ejecuté y descubrí que había una biblioteca liboit.sovinculada dinámicamente al ejecutable. Esta biblioteca fue instalada por elAuditor ObserveIT Unix, que intercepta toda la actividad de los usuarios que han iniciado sesión, incluidas las llamadas al sistema. Sin embargo, creo que simplemente interceptar las llamadas al sistema no daría como resultado el comportamiento observado, ya que la reejecución /bin/shse realiza dentro de glibc. Quizás ObserveIT también emule funciones POSIX, aparentemente no conformes en esta situación.

información relacionada