Skip to content

Commit 0bd8fa6

Browse files
authored
close_range improvements (#1114)
2 parents a981e39 + 5b42127 commit 0bd8fa6

File tree

9 files changed

+93
-223
lines changed

9 files changed

+93
-223
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ Suspected vulnerabilities can be reported on our [security page](https://github.
1313
An [audit of sudo-rs version 0.2.0](docs/audit/audit-report-sudo-rs.pdf) has been performed in August 2023.
1414
The findings from that audit are addressed in the current version.
1515

16-
Sudo-rs currently is targeted for Linux-based operating systems only; Linux kernel 5.9
17-
or newer is necessary to run sudo-rs.
16+
Sudo-rs currently is targeted for FreeBSD and Linux-based operating systems only.
1817

1918
## Installing sudo-rs
2019

src/common/error.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pub enum Error {
1313
other_user: Option<SudoString>,
1414
},
1515
SelfCheck,
16-
KernelCheck,
1716
CommandNotFound(PathBuf),
1817
InvalidCommand(PathBuf),
1918
ChDirNotAllowed {
@@ -61,7 +60,6 @@ impl fmt::Display for Error {
6160
Error::SelfCheck => {
6261
f.write_str("sudo must be owned by uid 0 and have the setuid bit set")
6362
}
64-
Error::KernelCheck => f.write_str("sudo-rs needs a Linux kernel newer than v5.9"),
6563
Error::CommandNotFound(p) => write!(f, "'{}': command not found", p.display()),
6664
Error::InvalidCommand(p) => write!(f, "'{}': invalid command", p.display()),
6765
Error::UserNotFound(u) => write!(f, "user '{u}' not found"),

src/exec/no_pty.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ use crate::{
1919
system::{
2020
_exit, fork, getpgid, getpgrp,
2121
interface::ProcessId,
22-
kill, killpg,
22+
kill, killpg, mark_fds_as_cloexec,
2323
term::{Terminal, UserTerm},
2424
wait::WaitOptions,
25-
FileCloser, ForkResult,
25+
ForkResult,
2626
},
2727
};
2828

@@ -39,17 +39,11 @@ pub(super) fn exec_no_pty(sudo_pid: ProcessId, mut command: Command) -> io::Resu
3939
}
4040
};
4141

42-
let mut file_closer = FileCloser::new();
43-
4442
// FIXME (ogsudo): Some extra config happens here if selinux is available.
4543

4644
// Use a pipe to get the IO error if `exec` fails.
4745
let (mut errpipe_tx, errpipe_rx) = BinPipe::pair()?;
4846

49-
// Don't close the error pipe as we need it to retrieve the error code if the command execution
50-
// fails.
51-
file_closer.except(&errpipe_tx);
52-
5347
// SAFETY: There should be no other threads at this point.
5448
let ForkResult::Parent(command_pid) = unsafe { fork() }.map_err(|err| {
5549
dev_warn!("unable to fork command process: {err}");
@@ -63,9 +57,7 @@ pub(super) fn exec_no_pty(sudo_pid: ProcessId, mut command: Command) -> io::Resu
6357
}
6458
}
6559

66-
// SAFETY: We immediately exec after this call and if the exec fails we only access stderr
67-
// and errpipe before exiting without running atexit handlers using _exit
68-
if let Err(err) = unsafe { file_closer.close_the_universe() } {
60+
if let Err(err) = mark_fds_as_cloexec() {
6961
dev_warn!("failed to close the universe: {err}");
7062
// Send the error to the monitor using the pipe.
7163
if let Some(error_code) = err.raw_os_error() {

src/exec/use_pty/monitor.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{
1919
use_pty::{SIGCONT_BG, SIGCONT_FG},
2020
},
2121
log::{dev_error, dev_info, dev_warn},
22-
system::FileCloser,
22+
system::mark_fds_as_cloexec,
2323
};
2424
use crate::{
2525
exec::{handle_sigchld, terminate_process, HandleSigchld},
@@ -40,7 +40,6 @@ pub(super) fn exec_monitor(
4040
command: Command,
4141
foreground: bool,
4242
backchannel: &mut MonitorBackchannel,
43-
mut file_closer: FileCloser,
4443
original_set: Option<SignalSet>,
4544
) -> io::Result<Infallible> {
4645
// SIGTTIN and SIGTTOU are ignored here but the docs state that it shouldn't
@@ -69,10 +68,6 @@ pub(super) fn exec_monitor(
6968
// Use a pipe to get the IO error if `exec_command` fails.
7069
let (errpipe_tx, errpipe_rx) = BinPipe::pair()?;
7170

72-
// Don't close the error pipe as we need it to retrieve the error code if the command execution
73-
// fails.
74-
file_closer.except(&errpipe_tx);
75-
7671
// Wait for the parent to give us green light before spawning the command. This avoids race
7772
// conditions when the command exits quickly.
7873
let event = retry_while_interrupted(|| backchannel.recv()).map_err(|err| {
@@ -93,14 +88,7 @@ pub(super) fn exec_monitor(
9388
else {
9489
drop(errpipe_rx);
9590

96-
match exec_command(
97-
command,
98-
foreground,
99-
pty_follower,
100-
file_closer,
101-
errpipe_tx,
102-
original_set,
103-
) {}
91+
match exec_command(command, foreground, pty_follower, errpipe_tx, original_set) {}
10492
};
10593

10694
// Send the command's PID to the parent.
@@ -192,7 +180,6 @@ fn exec_command(
192180
mut command: Command,
193181
foreground: bool,
194182
pty_follower: PtyFollower,
195-
file_closer: FileCloser,
196183
mut errpipe_tx: BinPipe<i32, i32>,
197184
original_set: Option<SignalSet>,
198185
) -> ! {
@@ -219,9 +206,7 @@ fn exec_command(
219206
}
220207
}
221208

222-
// SAFETY: We immediately exec after this call and if the exec fails we only access stderr
223-
// and errpipe before exiting without running atexit handlers using _exit
224-
if let Err(err) = unsafe { file_closer.close_the_universe() } {
209+
if let Err(err) = mark_fds_as_cloexec() {
225210
dev_warn!("failed to close the universe: {err}");
226211
// Send the error to the monitor using the pipe.
227212
if let Some(error_code) = err.raw_os_error() {

src/exec/use_pty/parent.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ use crate::system::signal::{
1919
};
2020
use crate::system::term::{Pty, PtyFollower, PtyLeader, TermSize, Terminal, UserTerm};
2121
use crate::system::wait::WaitOptions;
22-
use crate::system::{
23-
chown, fork, getpgrp, kill, killpg, FileCloser, ForkResult, Group, User, _exit,
24-
};
22+
use crate::system::{chown, fork, getpgrp, kill, killpg, ForkResult, Group, User, _exit};
2523
use crate::system::{getpgid, interface::ProcessId};
2624

2725
use super::pipe::Pipe;
@@ -58,18 +56,12 @@ pub(in crate::exec) fn exec_pty(
5856
// Fetch the parent process group so we can signals to it.
5957
let parent_pgrp = getpgrp();
6058

61-
let mut file_closer = FileCloser::new();
62-
6359
// Set all the IO streams for the command to the follower side of the pty.
64-
let mut clone_follower = || -> io::Result<PtyFollower> {
65-
let follower = pty.follower.try_clone().map_err(|err| {
60+
let clone_follower = || -> io::Result<PtyFollower> {
61+
pty.follower.try_clone().map_err(|err| {
6662
dev_error!("cannot clone pty follower: {err}");
6763
err
68-
})?;
69-
// Don't close these as we will need them so they are dupped inside `Command::exec`.
70-
file_closer.except(&follower);
71-
72-
Ok(follower)
64+
})
7365
};
7466

7567
command.stdin(clone_follower()?);
@@ -181,7 +173,6 @@ pub(in crate::exec) fn exec_pty(
181173
command,
182174
foreground && !pipeline && !exec_bg,
183175
&mut backchannels.monitor,
184-
file_closer,
185176
original_set,
186177
) {
187178
Ok(exec_output) => match exec_output {},

src/sudo/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::common::resolve::CurrentUser;
44
use crate::common::Error;
55
use crate::log::dev_info;
66
use crate::system::interface::UserId;
7-
use crate::system::kernel::kernel_check;
87
use crate::system::timestamp::RecordScope;
98
use crate::system::User;
109
use crate::system::{time::Duration, timestamp::SessionRecordFile, Process};
@@ -67,7 +66,6 @@ fn sudo_process() -> Result<(), Error> {
6766
dev_info!("development logs are enabled");
6867

6968
self_check()?;
70-
kernel_check()?;
7169

7270
// parse cli options
7371
match SudoAction::from_env() {

src/system/kernel.rs

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)