On 10/4/2021 10:33 AM, Manuel Bouyer wrote:
Hello I'm trying to run a binary-only linux program under NetBSD 9.2. From what I found, the binary was built on Ubuntu 16.04 [...] As you can see above (ktrace -si output), the read on fd 3 in 26751 returns with an error as soon as the child does its execve(), just as if CLOSEEXEC was set in the child. But the dup2(4,1) should keep the write side open without CLOSEEXEC. The program does a similar sequence just before (also forking a shell to execute some command) and it works. Later when sh tries to write to stdout it gets a SIGPIPE. I couldn't reproduce this with a simple program. But it seems that I can't reproduce this clone call. It seems that we are called with flags 0x1200011, which would translate to CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, and a NULL stack pointer. But when run on linux, this clone syscall straces to CLONE_VM|CLONE_VFORK|SIGCHLD
I think that combination of flags is actually a "fork()" call, which glibc implements using clone. I found that through https://eli.thegreenplace.net/2018/launching-linux-threads-and-processes-with-clone/, which mentions that glibc has a ARCH_FORK macro, though it seems that the more recent code uses an arch_fork inline function: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/arch-fork.h;h=b846da08f98839aef336868de24850626428509c;hb=HEAD
I tried writing a program using fork(), vfork() or clone() but none of them would use the clone() syscall as do my linux binary. Any idea what could cause clone() to be used this way ?
Is your binary statically linked? Maybe it has a different glibc implementation from the .so that's on your system.
Eric
