From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 72521385C426; Mon, 23 Mar 2020 16:24:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 72521385C426 From: "adhemerval.zanella at linaro dot org" To: glibc-bugs@sourceware.org Subject: [Bug libc/25715] system() returns wrong errors when posix_spawn fails Date: Mon, 23 Mar 2020 16:24:54 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: libc X-Bugzilla-Version: 2.30 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: adhemerval.zanella at linaro dot org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: adhemerval.zanella at linaro dot org X-Bugzilla-Target-Milestone: 2.32 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: glibc-bugs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-bugs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Mar 2020 16:24:54 -0000 https://sourceware.org/bugzilla/show_bug.cgi?id=3D25715 --- Comment #1 from Adhemerval Zanella --- (In reply to pokogiv215 from comment #0) > On linux, I observe a call to system() claiming it's killed by sigbus when > really the underlying execv failed with E2BIG. See reproduction in [1]. >=20 > What I expected to see is system() returning with exit code 127, as per `= man > system`: > * If a shell could not be executed in the child process, then the > return value is as though the child shell terminated by calling _exit(2) > with the status 127. Yes, this is an issue introduced by 5fb7fc9635057. I am currently preparing= a=20 patch to fix it. >=20 > Less important, but what I also expected is for posix_spawn to return 0 in > this case and to fill in the pid, but instead it returns E2BIG and doesn't > fill in the pid, which is not the behavior described by posix_spawn's man > page: > The posix_spawn() and posix_spawnp() functions fail only in the ca= se > where the underlying fork(2) or vfork(2) call fails; in these cases, the= se > functions return an error number, which will > be one of the errors described for fork(2) or vfork(2). POSIX [1] and man-pages (which is not the canonical documentation of glibc)= [2]=20 documents that if there is an error before or during the fork(2) (which in glibc Linux implementation of posix_spawn is done by a clone call with CLONE_VFOR= K),=20 then no child is created, the contents of *pid are unspecified, and these= =20 functions return an error number. And this is what is happening since what = is throwing the error is the execve syscall (using your example): $ strace -f ./elf/ld-linux-x86-64.so.2 [...] ./bz25715=20 [...] [pid 16313] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) =3D 0 pid 16313] execve("/bin/sh", ["sh", "-c", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"...], 0x7ffcf2800f60 /* 78 vars */) =3D -1 E2BIG (Argument list too long) [pid 16313] exit_group(127) =3D ? [pid 16311] <... clone resumed> child_stack=3D0x7f35d0eb1ff0,=20 flags=3DCLONE_VM|CLONE_VFORK|SIGCHLD) =3D 16313 [pid 16313] +++ exited with 127 +++ Returning anything different than an error, in this case, does not make sen= se. [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.= html >=20 > The bad return value from system() was introduced in > 5fb7fc96350575c9adb1316833e48ca11553be49, which returns posix_spawn's res= ult > (an errno) from system (which returns a wait status). >=20 > The posix_spawn handling of errors in the child seems to have changed > unintentionally in 4b4d4056bb154603f36c6f8845757c1012758158 (because ec > didn't use to be set). >=20 >=20 > [1] >=20 > $ cat a.c > #include > #include > #include > #include > #include > #include > #include >=20 > int main(int argc, char* argv[], char** env) { > char cmd[150000]; > memset(cmd, 'a', sizeof(cmd)); > cmd[sizeof(cmd) - 1] =3D 0; > int ret =3D posix_spawn(NULL, "/bin/sh", 0, NULL, > (char *[]){"sh", "-c", (char *)cmd, 0}, env); > printf("posix_spawn returns: %d =3D %s\n", ret, strerror(ret)); > int wstatus =3D system(cmd); > if (WIFEXITED(wstatus)) { > printf("exited, status=3D%d\n", WEXITSTATUS(wstatus)); > } else if (WIFSIGNALED(wstatus)) { > printf("killed by signal %d =3D %s\n", WTERMSIG(wstatus), > strsignal(WTERMSIG(wstatus))); > } else if (WIFSTOPPED(wstatus)) { > printf("stopped by signal %d\n", WSTOPSIG(wstatus)); > } else if (WIFCONTINUED(wstatus)) { > printf("continued\n"); > } > return 0; > } > $ gcc a.c && ./a.out > posix_spawn returns: 7 =3D Argument list too long > killed by signal 7 =3D Bus error --=20 You are receiving this mail because: You are on the CC list for the bug.=