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

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



Resending the patch inline as a diff instead of an attachment, to follow mailing list conventions.

diff --git a/include/libbb.h b/include/libbb.h
index 1962d93..76a04c3 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1234,6 +1234,7 @@ int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
 #endif
 void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;

+#if !BB_MMU
 /* xvfork() can't be a _function_, return after vfork in child mangles stack
  * in the parent. It must be a macro. */
 #define xvfork() \
@@ -1243,8 +1244,12 @@ void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
                bb_simple_perror_msg_and_die("vfork"); \
        bb__xvfork_pid; \
 })
-#if BB_MMU
+#else
 pid_t xfork(void) FAST_FUNC;
+/* Using fork instead of vfork on MMU-enabled targets to avoid segmentation
+ * fault.
+ */
+#define xvfork() xfork()
 #endif
 void xvfork_parent_waits_and_exits(void) FAST_FUNC;

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: