Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Fri, 29 Dec 2017 10:48:48 +0100
From: Markus Wichmann <nullplan@....net>
To: musl@...ts.openwall.com
Subject: Conformance problem in system()

Hi all,

I was testing system() while SIGCHLD is ignored just now, and noticed a
difference between glibc and musl. That in itself is not alarming, but
it prompted me to look this function up in the standard, to see which
behavior was conforming better (or maybe both are).

The program was this:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
        perror("signal");
    int i = system("sleep 1");
    if (i != 0)
        fprintf(stderr, "system() == %d, %m\n", i);
    return i;
}

Glibc returns -1 from system() while musl returns 32512. errno is the
same in both cases, ECHILD. Which is also what waitpid() is returning.

SUSv4 specifies for system()'s return value:

| [...][I]f the termination status for the command language interpreter
| cannot be obtained, system() shall return -1 and set errno to indicate
| the error.

So, it turns out, glibc is conforming to the standard, and musl is not.
If waitpid() fails, then the status cannot be retrieved.

I don't know about other system calls, but I tend to view pointer
arguments to system calls as undefined after a failed call. The kernel
might deposit something in those variables, or it might not. In this
case, it does not, so the status returned is the value status was
initialized to at the start of system(), which is 0x7f00, the value I
observed. I think you were hoping to land under the umbrella of

| If command is not a null pointer, system() shall return the termination
| status of the command language interpreter in the format specified by
| waitpid().

But a failing waitpid() does not fetch the status at all.

I have attached a patch to correct this behavior, for your perusal.

Ciao,
Markus

View attachment "0002-Correctly-handle-failing-waitpid-in-system.patch" of type "text/x-diff" (1196 bytes)

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ