commit: f43378e14396fe5fad05bff13a73483740205881
Author: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
AuthorDate: Sat Mar 6 09:02:32 2021 +0000
Commit: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
CommitDate: Thu Mar 11 08:03:04 2021 +0000
URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=f43378e1
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 <AT> gentoo.org>
libsandbox/symbols.h.in | 1 +
libsandbox/wrapper-funcs/vfork.c | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
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"