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"

Reply via email to