Skip to content

Commit 8899d66

Browse files
committed
std.process.Child: block signals during clone()
1 parent a581642 commit 8899d66

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

lib/std/process/Child.zig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ const ChildArg = struct {
532532
dev_null_fd: posix.fd_t,
533533
argv_buf: [:null]?[*:0]const u8,
534534
envp: [*:null]const ?[*:0]const u8,
535+
sigmask: ?*posix.sigset_t,
535536
ret_err: RetErr,
536537
};
537538

@@ -565,6 +566,27 @@ fn spawnPosixChildHelper(arg: usize) callconv(.c) u8 {
565566
posix.setpgid(0, pid) catch |err| return forkChildErrReport(&child_arg.ret_err, err);
566567
}
567568

569+
if (native_os == .linux and child_arg.sigmask != null) {
570+
std.debug.assert(linux.SIG.DFL == null);
571+
for (1..linux.NSIG) |sig| {
572+
if (sig == posix.SIG.KILL or sig == posix.SIG.STOP) {
573+
continue;
574+
}
575+
if (sig > std.math.maxInt(u6)) {
576+
// XXX: We cannot disable all signals.
577+
// sigaction accepts u6, which is too narrow.
578+
break;
579+
}
580+
var old_act: posix.Sigaction = undefined;
581+
const new_act = mem.zeroes(posix.Sigaction);
582+
posix.sigaction(@intCast(sig), &new_act, &old_act);
583+
if (old_act.handler.handler == linux.SIG.IGN) {
584+
posix.sigaction(@intCast(sig), &old_act, null);
585+
}
586+
}
587+
posix.sigprocmask(posix.SIG.SETMASK, child_arg.sigmask, null);
588+
}
589+
568590
const err = switch (child_arg.self.expand_arg0) {
569591
.expand => posix.execvpeZ_expandArg0(.expand, child_arg.argv_buf.ptr[0].?, child_arg.argv_buf.ptr, child_arg.envp),
570592
.no_expand => posix.execvpeZ_expandArg0(.no_expand, child_arg.argv_buf.ptr[0].?, child_arg.argv_buf.ptr, child_arg.envp),
@@ -690,6 +712,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
690712
.dev_null_fd = dev_null_fd,
691713
.argv_buf = argv_buf,
692714
.envp = envp,
715+
.sigmask = null,
693716
.ret_err = undefined,
694717
};
695718

@@ -701,6 +724,10 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
701724
immediateExit(spawnPosixChildHelper(@intFromPtr(&child_arg)));
702725
}
703726
} else {
727+
var old_mask: posix.sigset_t = undefined;
728+
posix.sigprocmask(posix.SIG.SETMASK, &linux.all_mask, &old_mask);
729+
defer posix.sigprocmask(posix.SIG.SETMASK, &old_mask, null);
730+
child_arg.sigmask = &old_mask;
704731
child_arg.ret_err = null;
705732
// Although the stack is fixed sized, we alloc it here,
706733
// because stack-smashing protection may have higher overhead than allocation.

0 commit comments

Comments
 (0)