Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve command-line arguments #1862

Merged
merged 1 commit into from
May 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 67 additions & 2 deletions src/jailer/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,21 @@ const STDIN_FILENO: libc::c_int = 0;
const STDOUT_FILENO: libc::c_int = 1;
const STDERR_FILENO: libc::c_int = 2;

// Kernel-based virtual machine (hardware virtualization extensions)
// minor/major numbers are taken from
// https://www.kernel.org/doc/html/latest/admin-guide/devices.html
const DEV_KVM_WITH_NUL: &[u8] = b"/dev/kvm\0";
const DEV_KVM_MAJOR: u32 = 10;
ioanachirca marked this conversation as resolved.
Show resolved Hide resolved
const DEV_KVM_MINOR: u32 = 232;

// TUN/TAP device minor/major numbers are taken from
// www.kernel.org/doc/Documentation/networking/tuntap.txt
const DEV_NET_TUN_WITH_NUL: &[u8] = b"/dev/net/tun\0";
ioanachirca marked this conversation as resolved.
Show resolved Hide resolved
const DEV_NET_TUN_MAJOR: u32 = 10;
const DEV_NET_TUN_MINOR: u32 = 200;

const DEV_NULL_WITH_NUL: &[u8] = b"/dev/null\0";
ioanachirca marked this conversation as resolved.
Show resolved Hide resolved

// Relevant folders inside the jail that we create or/and for which we change ownership.
// We need /dev in order to be able to create /dev/kvm and /dev/net/tun device.
// We need /run for the default location of the api socket.
Expand Down Expand Up @@ -280,9 +292,9 @@ impl Env {
// $: mknod $dev_net_tun_path c 10 200
// www.kernel.org/doc/Documentation/networking/tuntap.txt specifies 10 and 200 as the major
// and minor for the /dev/net/tun device.
self.mknod_and_own_dev(DEV_NET_TUN_WITH_NUL, 10, 200)?;
self.mknod_and_own_dev(DEV_NET_TUN_WITH_NUL, DEV_NET_TUN_MAJOR, DEV_NET_TUN_MINOR)?;
// Do the same for /dev/kvm with (major, minor) = (10, 232).
self.mknod_and_own_dev(DEV_KVM_WITH_NUL, 10, 232)?;
self.mknod_and_own_dev(DEV_KVM_WITH_NUL, DEV_KVM_MAJOR, DEV_KVM_MINOR)?;

// Daemonize before exec, if so required (when the dev_null variable != None).
if let Some(fd) = dev_null {
Expand Down Expand Up @@ -546,4 +558,57 @@ mod tests {
// And changing the umask in the Python integration tests is unsafe because of pytest's
// process management; it can't be isolated from side effects.
}

fn skip_not_found(err: std::io::Error) -> std::io::Result<()> {
match err.kind() {
std::io::ErrorKind::NotFound => Ok(()),
_ => Err(err),
}
}

fn get_major(dev: u64) -> u32 {
unsafe { libc::major(dev) }
}

fn get_minor(dev: u64) -> u32 {
unsafe { libc::minor(dev) }
}

#[test]
fn test_mknod_and_own_dev() {
use std::os::unix::fs::FileTypeExt;

// Create a standard environment.
let arg_parser = build_arg_parser();
let mut args = arg_parser.arguments().clone();
args.parse(&make_args(&ArgVals::new())).unwrap();
let env = Env::new(&args, 0, 0).unwrap();

// Ensure path buffers without NULL-termination are handled well.
assert!(env.mknod_and_own_dev(b"/some/path", 0, 0).is_err());

// Ensure device nodes are created with correct major/minor numbers and permissions.
let dev_infos: Vec<(&[u8], u32, u32)> = vec![
(b"/dev/net/tun-test\0", DEV_NET_TUN_MAJOR, DEV_NET_TUN_MINOR),
(b"/dev/kvm-test\0", DEV_KVM_MAJOR, DEV_KVM_MINOR),
];

for (dev, major, minor) in dev_infos {
let dev_str = CStr::from_bytes_with_nul(dev).unwrap().to_str().unwrap();

// Create a new device node (removing the old one if needed).
fs::remove_file(dev_str).or_else(skip_not_found).unwrap();
env.mknod_and_own_dev(dev, major, minor).unwrap();

// Ensure device's properties.
let metadata = fs::metadata(dev_str).unwrap();
assert_eq!(metadata.file_type().is_char_device(), true);
assert_eq!(get_major(metadata.st_rdev()), major);
assert_eq!(get_minor(metadata.st_rdev()), minor);
assert_eq!(
metadata.permissions().mode(),
libc::S_IFCHR | libc::S_IRUSR | libc::S_IWUSR
);
}
}
}
2 changes: 1 addition & 1 deletion tests/integration_tests/build/test_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# this contains the frequency while on AMD it does not.
# Checkout the cpuid crate. In the future other
# differences may appear.
COVERAGE_DICT = {"Intel": 84.32, "AMD": 84.26}
COVERAGE_DICT = {"Intel": 84.42, "AMD": 84.38}
PROC_MODEL = proc.proc_type()

COVERAGE_MAX_DELTA = 0.05
Expand Down