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

tshah <[email protected]>
Newsgroups gmane.linux.busybox,gmane.linux.debian.ports.powerpc
Message-ID <[email protected]>
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
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox
fix-runc-seg-fault.patch (text/x-patch, 802 B)
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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.