aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Trofimovich <slyfox@gentoo.org>2021-03-06 09:02:32 +0000
committerSergei Trofimovich <slyfox@gentoo.org>2021-03-11 08:03:04 +0000
commitf43378e14396fe5fad05bff13a73483740205881 (patch)
treef51fd176e30ccd89922c1430fce5cd21d838eb77
parentconfigure.ac: use tool-prefixed READELF (diff)
downloadsandbox-f43378e14396fe5fad05bff13a73483740205881.tar.gz
sandbox-f43378e14396fe5fad05bff13a73483740205881.tar.bz2
sandbox-f43378e14396fe5fad05bff13a73483740205881.zip
libsandbox: implement vfork() via fork()
sandbox turns vfork()/exec("/sbin/ldconfig") into vfork()/ptrace()+fork()/exec("/sbin/ldconfig"). It happens because "/sbin/ldconfig" is a static binary and can't be inspected via LD_PRELOAD and sandbox falls back to fork()+ptrace() vfork() imposes very strong requirements on what could happen between vfork() and exec(). Above sandbox behaviour violates it. vfork() is specified in a way that it can always can be substituted for fork(). This change does exactly that. Reported-by: Michał Górny Bug: https://bugs.gentoo.org/774054 Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
-rw-r--r--libsandbox/symbols.h.in1
-rw-r--r--libsandbox/wrapper-funcs/vfork.c28
2 files changed, 29 insertions, 0 deletions
diff --git a/libsandbox/symbols.h.in b/libsandbox/symbols.h.in
index bdbce08..0154c2a 100644
--- a/libsandbox/symbols.h.in
+++ b/libsandbox/symbols.h.in
@@ -74,3 +74,4 @@ utimensat
futimesat
lutimes
fork
+vfork
diff --git a/libsandbox/wrapper-funcs/vfork.c b/libsandbox/wrapper-funcs/vfork.c
new file mode 100644
index 0000000..b28e74c
--- /dev/null
+++ b/libsandbox/wrapper-funcs/vfork.c
@@ -0,0 +1,28 @@
+/*
+ * vfork() wrapper.
+ *
+ * Copyright 1999-2021 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+/* We're only wrapping vfork() as a poor man's pthread_atfork(). That would
+ * require dedicated linkage against libpthread. So here we force the locks
+ * to a consistent state before forking.
+ *
+ * We also implement vfork() as fork() because sandbox does not meet vfork()
+ * requirements bet ween vfork()/exec("some-static-bianary") because we launch
+ * ptrace in the middle.
+ */
+
+#define WRAPPER_ARGS_PROTO
+#define WRAPPER_ARGS
+#define WRAPPER_SAFE() 0
+#define WRAPPER_PRE_CHECKS() \
+({ \
+ /* pthread_atfork(sb_lock, sb_unlock, sb_unlock); */ \
+ sb_lock(); \
+ result = sb_unwrapped_fork_DEFAULT(WRAPPER_ARGS_FULL); \
+ sb_unlock(); \
+ false; \
+})
+#include "__wrapper_simple.c"