Skip to content

Commit 2f9d3db

Browse files
committed
add more Rustified version of kernel_check
1 parent 1c68e19 commit 2f9d3db

File tree

3 files changed

+37
-29
lines changed

3 files changed

+37
-29
lines changed

src/common/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl fmt::Display for Error {
5757
Error::SelfCheck => {
5858
f.write_str("sudo must be owned by uid 0 and have the setuid bit set")
5959
}
60-
Error::KernelCheck => f.write_str("sudo needs a Kernel >= 5.9"),
60+
Error::KernelCheck => f.write_str("sudo-rs needs a Linux kernel newer than v5.9"),
6161
Error::CommandNotFound(p) => write!(f, "'{}': command not found", p.display()),
6262
Error::InvalidCommand(p) => write!(f, "'{}': invalid command", p.display()),
6363
Error::UserNotFound(u) => write!(f, "user '{u}' not found"),

src/sudo/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ fn sudo_process() -> Result<(), Error> {
111111
dev_info!("development logs are enabled");
112112

113113
self_check()?;
114-
kernel_check(5, 9)?;
114+
kernel_check()?;
115115

116116
let pipeline = Pipeline {
117117
policy: SudoersPolicy::default(),

src/system/kernel.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,49 @@
11
use std::ffi::CStr;
22

3-
use std::mem::zeroed;
3+
use std::mem::MaybeUninit;
44

5-
use crate::common::Error;
5+
use crate::{common::Error, cutils::cerr};
66

7-
pub fn kernel_check(major: u32, minor: u32) -> Result<(), Error> {
8-
if cfg!(target_os = "freebsd") {
9-
return Ok(());
10-
}
7+
#[cfg(target_os = "linux")]
8+
pub fn kernel_check() -> Result<(), Error> {
9+
// On Linux, we need kernel version 5.9 to have access to `close_range()`
10+
const TARGET_VERSION: (u32, u32) = (5, 9);
1111

12-
let mut utsname: libc::utsname = unsafe { zeroed() };
12+
let mut utsname = MaybeUninit::uninit();
1313

14-
if unsafe { libc::uname(&mut utsname) } != 0 {
15-
// Could not get the kernel version. Try to run anyway
16-
return Ok(());
17-
}
14+
// SAFETY: uname is passed a correct pointer
15+
cerr(unsafe { libc::uname(utsname.as_mut_ptr()) })?;
1816

19-
let release = unsafe { CStr::from_ptr(utsname.release.as_ptr()) }
20-
.to_string_lossy()
21-
.into_owned();
17+
// SAFETY: since uname exited normally, the struct is now initialized
18+
let utsname = unsafe { utsname.assume_init() };
2219

23-
let version_parts: Vec<&str> = release.split('.').collect();
24-
25-
if version_parts.len() < 2 {
26-
// Could not get the kernel version. Try to run anyway
27-
return Ok(());
28-
}
20+
// SAFETY: utsname.release will hold a null-terminated C string
21+
let release = unsafe { CStr::from_ptr(utsname.release.as_ptr()) }.to_string_lossy();
2922

3023
// Parse the major and minor version numbers
31-
if let (Ok(major_version), Ok(minor_version)) = (
32-
version_parts[0].parse::<u32>(),
33-
version_parts[1].parse::<u32>(),
34-
) {
35-
if major_version > major || (major_version == major && minor_version >= minor) {
36-
return Ok(());
24+
let mut version_parts = release.split('.').map_while(|x| x.parse::<u32>().ok());
25+
26+
match (version_parts.next(), version_parts.next()) {
27+
(Some(major), Some(minor)) if (major, minor) < TARGET_VERSION => {
28+
// We have determined that this Linux kernel is too old.
29+
Err(Error::KernelCheck)
30+
}
31+
_ => {
32+
// We have not been able to prove that sudo-rs is incompatible with this kernel
33+
// and are giving the benefit of the doubt.
34+
Ok(())
3735
}
3836
}
37+
}
38+
39+
#[cfg(target_os = "freebsd")]
40+
pub fn kernel_check() -> Result<(), Error> {
41+
// the kernel check doesn't make much sense on FreeBSD (we need FreeBSD 8.0 or newer,
42+
// which is comparatively ancient compared to Linux 5.9)
43+
Ok(())
44+
}
3945

40-
Err(Error::KernelCheck)
46+
#[cfg(not(any(target_os = "freebsd", target_os = "linux")))]
47+
pub fn kernel_check() -> Result<(), Error> {
48+
compile_error!("sudo-rs only works on Linux and FreeBSD");
4149
}

0 commit comments

Comments
 (0)