[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
- posix_spawn[p] less secure on Hurd than on Linux,
Bruno Haible <=