Skip to content

Commit 2e0d417

Browse files
committed
Spawn seccomp_unotify handler thread after forking
1 parent 09a5f7a commit 2e0d417

File tree

4 files changed

+46
-16
lines changed

4 files changed

+46
-16
lines changed

src/exec/mod.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,17 @@ pub fn run_command(
8282
command.arg0(OsStr::from_bytes(&process_name));
8383
}
8484

85-
if options.noexec {
86-
#[cfg(target_os = "linux")]
87-
noexec::add_noexec_filter(&mut command, &mut file_closer);
88-
85+
let spawn_noexec_handler = if options.noexec {
8986
#[cfg(not(target_os = "linux"))]
9087
return Err(io::Error::other(
9188
"NOEXEC is currently only supported on Linux",
9289
));
93-
}
90+
91+
#[cfg(target_os = "linux")]
92+
Some(noexec::add_noexec_filter(&mut command, &mut file_closer))
93+
} else {
94+
None
95+
};
9496

9597
// Decide if the pwd should be changed. `--chdir` takes precedence over `-i`.
9698
let path = options
@@ -126,14 +128,20 @@ pub fn run_command(
126128

127129
if options.use_pty {
128130
match UserTerm::open() {
129-
Ok(user_tty) => exec_pty(sudo_pid, file_closer, command, user_tty),
131+
Ok(user_tty) => exec_pty(
132+
sudo_pid,
133+
file_closer,
134+
spawn_noexec_handler,
135+
command,
136+
user_tty,
137+
),
130138
Err(err) => {
131139
dev_info!("Could not open user's terminal, not allocating a pty: {err}");
132-
exec_no_pty(sudo_pid, file_closer, command)
140+
exec_no_pty(sudo_pid, file_closer, spawn_noexec_handler, command)
133141
}
134142
}
135143
} else {
136-
exec_no_pty(sudo_pid, file_closer, command)
144+
exec_no_pty(sudo_pid, file_closer, spawn_noexec_handler, command)
137145
}
138146
}
139147

src/exec/no_pty.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
},
1515
};
1616
use crate::{
17-
exec::{exec_command, handle_sigchld, signal_fmt},
17+
exec::{exec_command, handle_sigchld, noexec::SpawnNoexecHandler, signal_fmt},
1818
log::{dev_error, dev_info, dev_warn},
1919
system::{
2020
fork, getpgid, getpgrp,
@@ -29,6 +29,7 @@ use crate::{
2929
pub(super) fn exec_no_pty(
3030
sudo_pid: ProcessId,
3131
mut file_closer: FileCloser,
32+
spawn_noexec_handler: Option<SpawnNoexecHandler>,
3233
command: Command,
3334
) -> io::Result<ExitReason> {
3435
// FIXME (ogsudo): Initialize the policy plugin's session here.
@@ -61,6 +62,10 @@ pub(super) fn exec_no_pty(
6162
exec_command(file_closer, command, original_set, errpipe_tx);
6263
};
6364

65+
if let Some(spawner) = spawn_noexec_handler {
66+
spawner.spawn();
67+
}
68+
6469
dev_info!("executed command with pid {command_pid}");
6570

6671
let mut registry = EventRegistry::new();

src/exec/noexec.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,14 +255,23 @@ fn send_fd(tx_fd: UnixStream, notify_fd: RawFd) -> io::Result<()> {
255255
}
256256
}
257257

258-
pub(crate) fn add_noexec_filter(command: &mut Command, file_closer: &mut FileCloser) {
259-
let (tx_fd, rx_fd) = UnixStream::pair().unwrap();
258+
pub(super) struct SpawnNoexecHandler(UnixStream);
259+
260+
impl SpawnNoexecHandler {
261+
pub(super) fn spawn(self) {
262+
thread::spawn(move || {
263+
let notify_fd = receive_fd(self.0);
264+
// SAFETY: notify_fd is a valid seccomp_unotify fd.
265+
unsafe { handle_notifications(OwnedFd::from_raw_fd(notify_fd)) };
266+
});
267+
}
268+
}
260269

261-
thread::spawn(move || {
262-
let notify_fd = receive_fd(rx_fd);
263-
// SAFETY: notify_fd is a valid seccomp_unotify fd.
264-
unsafe { handle_notifications(OwnedFd::from_raw_fd(notify_fd)) };
265-
});
270+
pub(crate) fn add_noexec_filter(
271+
command: &mut Command,
272+
file_closer: &mut FileCloser,
273+
) -> SpawnNoexecHandler {
274+
let (tx_fd, rx_fd) = UnixStream::pair().unwrap();
266275

267276
file_closer.except(&tx_fd);
268277

@@ -327,4 +336,6 @@ pub(crate) fn add_noexec_filter(command: &mut Command, file_closer: &mut FileClo
327336
Ok(())
328337
});
329338
}
339+
340+
SpawnNoexecHandler(rx_fd)
330341
}

src/exec/use_pty/parent.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::io;
44
use std::process::{Command, Stdio};
55

66
use crate::exec::event::{EventHandle, EventRegistry, PollEvent, Process, StopReason};
7+
use crate::exec::noexec::SpawnNoexecHandler;
78
use crate::exec::use_pty::monitor::exec_monitor;
89
use crate::exec::use_pty::SIGCONT_FG;
910
use crate::exec::{cond_fmt, handle_sigchld, signal_fmt, terminate_process, HandleSigchld};
@@ -30,6 +31,7 @@ use super::{CommandStatus, SIGCONT_BG};
3031
pub(in crate::exec) fn exec_pty(
3132
sudo_pid: ProcessId,
3233
mut file_closer: FileCloser,
34+
spawn_noexec_handler: Option<SpawnNoexecHandler>,
3335
mut command: Command,
3436
user_tty: UserTerm,
3537
) -> io::Result<ExitReason> {
@@ -205,6 +207,10 @@ pub(in crate::exec) fn exec_pty(
205207
_exit(1);
206208
};
207209

210+
if let Some(spawner) = spawn_noexec_handler {
211+
spawner.spawn();
212+
}
213+
208214
// Close the file descriptors that we don't access
209215
drop(pty.follower);
210216
drop(backchannels.monitor);

0 commit comments

Comments
 (0)