浏览代码

block uid/gid changes during posix_spawn

usage of vfork creates a situation where a process of lower privilege
may momentarily have write access to the memory of a process of higher
privilege.

consider the case of a multi-threaded suid program which is calling
posix_spawn in one thread while another thread drops the elevated
privileges then runs untrusted (relative to the elevated privilege)
code as the original invoking user. this untrusted code can then
potentially modify the data the child process will use before calling
exec, for example changing the pathname or arguments that will be
passed to exec.

note that if vfork is implemented as fork, the lock will not be held
until the child execs, but since memory is not shared it does not
matter.
Rich Felker 12 年之前
父节点
当前提交
d5304147b9
共有 1 个文件被更改,包括 10 次插入0 次删除
  1. 10 0
      src/process/posix_spawn.c

+ 10 - 0
src/process/posix_spawn.c

@@ -5,9 +5,16 @@
 #include <fcntl.h>
 #include "syscall.h"
 #include "fdop.h"
+#include "libc.h"
 
 extern char **environ;
 
+static void dummy_0()
+{
+}
+weak_alias(dummy_0, __acquire_ptc);
+weak_alias(dummy_0, __release_ptc);
+
 pid_t __vfork(void);
 
 int __posix_spawnx(pid_t *restrict res, const char *restrict path,
@@ -24,7 +31,10 @@ int __posix_spawnx(pid_t *restrict res, const char *restrict path,
 	if (!attr) attr = &dummy_attr;
 
 	sigprocmask(SIG_BLOCK, (void *)(uint64_t []){-1}, &oldmask);
+
+	__acquire_ptc();
 	pid = __vfork();
+	__release_ptc();
 
 	if (pid) {
 		sigprocmask(SIG_SETMASK, &oldmask, 0);