diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/nix/test/test_kmod | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/nix/test/test_kmod')
-rw-r--r-- | third_party/rust/nix/test/test_kmod/hello_mod/Makefile | 7 | ||||
-rw-r--r-- | third_party/rust/nix/test/test_kmod/hello_mod/hello.c | 26 | ||||
-rw-r--r-- | third_party/rust/nix/test/test_kmod/mod.rs | 188 |
3 files changed, 221 insertions, 0 deletions
diff --git a/third_party/rust/nix/test/test_kmod/hello_mod/Makefile b/third_party/rust/nix/test/test_kmod/hello_mod/Makefile new file mode 100644 index 0000000000..74c99b77e9 --- /dev/null +++ b/third_party/rust/nix/test/test_kmod/hello_mod/Makefile @@ -0,0 +1,7 @@ +obj-m += hello.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean diff --git a/third_party/rust/nix/test/test_kmod/hello_mod/hello.c b/third_party/rust/nix/test/test_kmod/hello_mod/hello.c new file mode 100644 index 0000000000..1c34987d2a --- /dev/null +++ b/third_party/rust/nix/test/test_kmod/hello_mod/hello.c @@ -0,0 +1,26 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ or MIT + */ +#include <linux/module.h> +#include <linux/kernel.h> + +static int number= 1; +static char *who = "World"; + +module_param(number, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(myint, "Just some number"); +module_param(who, charp, 0000); +MODULE_PARM_DESC(who, "Whot to greet"); + +int init_module(void) +{ + printk(KERN_INFO "Hello %s (%d)!\n", who, number); + return 0; +} + +void cleanup_module(void) +{ + printk(KERN_INFO "Goodbye %s (%d)!\n", who, number); +} + +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/third_party/rust/nix/test/test_kmod/mod.rs b/third_party/rust/nix/test/test_kmod/mod.rs new file mode 100644 index 0000000000..6f9aaa897f --- /dev/null +++ b/third_party/rust/nix/test/test_kmod/mod.rs @@ -0,0 +1,188 @@ +use crate::*; +use std::fs::copy; +use std::path::PathBuf; +use std::process::Command; +use tempfile::{tempdir, TempDir}; + +fn compile_kernel_module() -> (PathBuf, String, TempDir) { + let _m = crate::FORK_MTX.lock(); + + let tmp_dir = + tempdir().expect("unable to create temporary build directory"); + + copy( + "test/test_kmod/hello_mod/hello.c", + tmp_dir.path().join("hello.c"), + ) + .expect("unable to copy hello.c to temporary build directory"); + copy( + "test/test_kmod/hello_mod/Makefile", + tmp_dir.path().join("Makefile"), + ) + .expect("unable to copy Makefile to temporary build directory"); + + let status = Command::new("make") + .current_dir(tmp_dir.path()) + .status() + .expect("failed to run make"); + + assert!(status.success()); + + // Return the relative path of the build kernel module + (tmp_dir.path().join("hello.ko"), "hello".to_owned(), tmp_dir) +} + +use nix::errno::Errno; +use nix::kmod::{delete_module, DeleteModuleFlags}; +use nix::kmod::{finit_module, init_module, ModuleInitFlags}; +use std::ffi::CString; +use std::fs::File; +use std::io::Read; + +#[test] +fn test_finit_and_delete_module() { + require_capability!("test_finit_and_delete_module", CAP_SYS_MODULE); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let f = File::open(kmod_path).expect("unable to open kernel module"); + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_finit_and_delete_module_with_params() { + require_capability!( + "test_finit_and_delete_module_with_params", + CAP_SYS_MODULE + ); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let f = File::open(kmod_path).expect("unable to open kernel module"); + finit_module( + &f, + &CString::new("who=Rust number=2018").unwrap(), + ModuleInitFlags::empty(), + ) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_init_and_delete_module() { + require_capability!("test_init_and_delete_module", CAP_SYS_MODULE); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let mut f = File::open(kmod_path).expect("unable to open kernel module"); + let mut contents: Vec<u8> = Vec::new(); + f.read_to_end(&mut contents) + .expect("unable to read kernel module content to buffer"); + init_module(&contents, &CString::new("").unwrap()) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_init_and_delete_module_with_params() { + require_capability!( + "test_init_and_delete_module_with_params", + CAP_SYS_MODULE + ); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let mut f = File::open(kmod_path).expect("unable to open kernel module"); + let mut contents: Vec<u8> = Vec::new(); + f.read_to_end(&mut contents) + .expect("unable to read kernel module content to buffer"); + init_module(&contents, &CString::new("who=Nix number=2015").unwrap()) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_finit_module_invalid() { + require_capability!("test_finit_module_invalid", CAP_SYS_MODULE); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let kmod_path = "/dev/zero"; + + let f = File::open(kmod_path).expect("unable to open kernel module"); + let result = + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); + + assert_eq!(result.unwrap_err(), Errno::EINVAL); +} + +#[test] +fn test_finit_module_twice_and_delete_module() { + require_capability!( + "test_finit_module_twice_and_delete_module", + CAP_SYS_MODULE + ); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let f = File::open(kmod_path).expect("unable to open kernel module"); + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()) + .expect("unable to load kernel module"); + + let result = + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); + + assert_eq!(result.unwrap_err(), Errno::EEXIST); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_delete_module_not_loaded() { + require_capability!("test_delete_module_not_loaded", CAP_SYS_MODULE); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let result = delete_module( + &CString::new("hello").unwrap(), + DeleteModuleFlags::empty(), + ); + + assert_eq!(result.unwrap_err(), Errno::ENOENT); +} |