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

Re: [PATCH] Replace vfork() with fork() to fix unshare crash on ppc64le



Hello Denys,

Can you please look into this change and let me know your thoughts  on this once you get chance.

Thanks.

On 09/09/25 15:50, tshah wrote:
Hello,

This patch address the issue: https://lists.busybox.net/pipermail/busybox/2025-September/091718.html. The patch replaces the use of vfork() with fork() on MMU-enabled targets in the xvfork() macro. This change is necessary to resolve a segmentation fault observed on ppc64le when running: "unshare -mrpf sh".

According to POSIX, there is an udefined behaviour if the child process created by vfork() either modifies the data other than a variable of type pid_t or calls any other functions before successfully calling exec (3) or _exit(2) family functions. From the strace logs,it looks like the child after vfork performed syscalls like writing uid_map, gid_map, mounting, etc, which violates the minimal action requirements of vfork() resulting in a SIGSEGV maybe due to race conditions.

[ 189] [00003fff9376726c] vfork(strace: Process 376786 attached
 <unfinished ...>
[pid 376786] [ 286] [00003fff936d7a80] openat(AT_FDCWD, "/proc/self/setgroups", O_WRONLY) = 3
[pid 376786] [   4] [00003fff936d7a80] write(3, "deny", 4) = 4
[pid 376786] [   6] [00003fff936d7a80] close(3) = 0
[pid 376786] [ 286] [00003fff936d7a80] openat(AT_FDCWD, "/proc/self/uid_map", O_WRONLY) = 3
[pid 376786] [   4] [00003fff936d7a80] write(3, "0 1000 1", 8) = 8
[pid 376786] [   6] [00003fff936d7a80] close(3) = 0
[pid 376786] [ 286] [00003fff936d7a80] openat(AT_FDCWD, "/proc/self/gid_map", O_WRONLY) = 3
[pid 376786] [   4] [00003fff936d7a80] write(3, "0 1000 1", 8) = 8
[pid 376786] [   6] [00003fff936d7a80] close(3) = 0
[pid 376786] [  21] [00003fff937890fc] mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) = 0 [pid 376786] [  11] [00003fff93741230] execve("/usr/local/bin/bash", ["bash", "-c", "ls"], 0x3fffe38b2780 /* 22 vars */) = -1 ENOENT (No such file or directory) [pid 376786] [  11] [00003fff93741230] execve("/usr/bin/bash", ["bash", "-c", "ls"], 0x3fffe38b2780 /* 22 vars */ <unfinished ...>
[pid 376785] [ 189] [00003fff9376726c] <... vfork resumed>) = 376786
[pid 376785] [ 189] [f37838210030e840] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_BNDERR, si_addr=0xf37838210030e840, si_lower=NULL, si_upper=NULL} ---
[pid 376786] [  11] [00003fffaf368aa0] <... execve resumed>) = 0
[pid 376786] [  45] [00003fffaf371188] brk(NULL) = 0x100157a6000
[pid 376786] [  90] [00003fffaf374638] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x3fffaf391000 [pid 376786] [  33] [00003fffaf373e90] access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) [pid 376786] [ 286] [00003fffaf374340] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 376785] [ 189] [????????????????] +++ killed by SIGSEGV +++


Replacing vfork() with fork() will eliminate this issue because fork() creates a separate memory space, so the child’s operations cannot corrupt the parent’s stack and both processes operate independently.

_______________________________________________
busybox mailing list
busybox@busybox.net
https://lists.busybox.net/mailman/listinfo/busybox


Reply to: