bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

posix_spawn[p] less secure on Hurd than on Linux


From: Bruno Haible
Subject: posix_spawn[p] less secure on Hurd than on Linux
Date: Thu, 24 Dec 2020 02:54:28 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-197-generic; KDE/5.18.0; x86_64; ; )

Hi,

In glibc versions < 2.15, posix_spawn and posix_spawnp did execute a
script (with execution bits set) even if it did not start with a '#!'
marker. Then, /bin/sh was used as an interpreter.

You can imagine how easily a text file, which happens to set execution
bits set because it was copied from a samba/cifs mount, can get executed.

Apparently this is considered unsecure, and since POSIX
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html>
is silent on this aspect, this misfeature was withdrawn from glibc in

<https://sourceware.org/bugzilla/show_bug.cgi?id=13134> and
<https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d96de9634a334af16c0ac711074c15ac1762b23c>.

But the test programs that I wrote for this show that, unlike on
GNU/Linux, on GNU/Hurd such scripts are still executed.

How to reproduce:

1) Preparations:

$ echo ':' > conftest.scr
$ chmod a+x conftest.scr

2) Test case for posix_spawn:

       #include <errno.h>
       #include <spawn.h>
       #include <stddef.h>
       #include <sys/types.h>
       #include <sys/wait.h>
       int
       main ()
       {
         const char *prog_path = "./conftest.scr";
         const char *prog_argv[2] = { prog_path, NULL };
         const char *environment[2] = { "PATH=.", NULL };
         pid_t child;
         int status;
         int err = posix_spawn (&child, prog_path, NULL, NULL,
                                (char **) prog_argv, (char **) environment);
         if (err == ENOEXEC)
           return 0;
         if (err != 0)
           return 1;
         status = 0;
         while (waitpid (child, &status, 0) != child)
           ;
         if (!WIFEXITED (status))
           return 2;
         if (WEXITSTATUS (status) != 127)
           return 3;
         return 0;
       }

3) Test case for posix_spawnp:

       #include <errno.h>
       #include <spawn.h>
       #include <stddef.h>
       #include <sys/types.h>
       #include <sys/wait.h>
       int
       main ()
       {
         const char *prog_path = "./conftest.scr";
         const char *prog_argv[2] = { prog_path, NULL };
         const char *environment[2] = { "PATH=.", NULL };
         pid_t child;
         int status;
         int err = posix_spawnp (&child, prog_path, NULL, NULL,
                                 (char **) prog_argv, (char **) environment);
         if (err == ENOEXEC)
           return 0;
         if (err != 0)
           return 1;
         status = 0;
         while (waitpid (child, &status, 0) != child)
           ;
         if (!WIFEXITED (status))
           return 2;
         if (WEXITSTATUS (status) != 127)
           return 3;
         return 0;
       }

4) Compile and run the program.
   Expected exit code: 0
   Actual exit code: 3

You probably need strace to see what's happing under the hood.

Seen on a glibc 2.28 system.

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]