• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::fs::copy;
2 use std::path::PathBuf;
3 use std::process::Command;
4 use tempfile::{tempdir, TempDir};
5 use crate::*;
6 
compile_kernel_module() -> (PathBuf, String, TempDir)7 fn compile_kernel_module() -> (PathBuf, String, TempDir) {
8     let _m = crate::FORK_MTX.lock();
9 
10     let tmp_dir = tempdir().expect("unable to create temporary build directory");
11 
12     copy(
13         "test/test_kmod/hello_mod/hello.c",
14         &tmp_dir.path().join("hello.c"),
15     ).expect("unable to copy hello.c to temporary build directory");
16     copy(
17         "test/test_kmod/hello_mod/Makefile",
18         &tmp_dir.path().join("Makefile"),
19     ).expect("unable to copy Makefile to temporary build directory");
20 
21     let status = Command::new("make")
22         .current_dir(tmp_dir.path())
23         .status()
24         .expect("failed to run make");
25 
26     assert!(status.success());
27 
28     // Return the relative path of the build kernel module
29     (tmp_dir.path().join("hello.ko"), "hello".to_owned(), tmp_dir)
30 }
31 
32 use nix::errno::Errno;
33 use nix::kmod::{delete_module, DeleteModuleFlags};
34 use nix::kmod::{finit_module, init_module, ModuleInitFlags};
35 use std::ffi::CString;
36 use std::fs::File;
37 use std::io::Read;
38 
39 #[test]
test_finit_and_delete_module()40 fn test_finit_and_delete_module() {
41     require_capability!("test_finit_and_delete_module", CAP_SYS_MODULE);
42     let _m0 = crate::KMOD_MTX.lock();
43     let _m1 = crate::CWD_LOCK.read();
44 
45     let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
46 
47     let f = File::open(kmod_path).expect("unable to open kernel module");
48     finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty())
49         .expect("unable to load kernel module");
50 
51     delete_module(
52         &CString::new(kmod_name).unwrap(),
53         DeleteModuleFlags::empty(),
54     ).expect("unable to unload kernel module");
55 }
56 
57 #[test]
test_finit_and_delete_module_with_params()58 fn test_finit_and_delete_module_with_params() {
59     require_capability!("test_finit_and_delete_module_with_params", CAP_SYS_MODULE);
60     let _m0 = crate::KMOD_MTX.lock();
61     let _m1 = crate::CWD_LOCK.read();
62 
63     let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
64 
65     let f = File::open(kmod_path).expect("unable to open kernel module");
66     finit_module(
67         &f,
68         &CString::new("who=Rust number=2018").unwrap(),
69         ModuleInitFlags::empty(),
70     ).expect("unable to load kernel module");
71 
72     delete_module(
73         &CString::new(kmod_name).unwrap(),
74         DeleteModuleFlags::empty(),
75     ).expect("unable to unload kernel module");
76 }
77 
78 #[test]
test_init_and_delete_module()79 fn test_init_and_delete_module() {
80     require_capability!("test_init_and_delete_module", CAP_SYS_MODULE);
81     let _m0 = crate::KMOD_MTX.lock();
82     let _m1 = crate::CWD_LOCK.read();
83 
84     let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
85 
86     let mut f = File::open(kmod_path).expect("unable to open kernel module");
87     let mut contents: Vec<u8> = Vec::new();
88     f.read_to_end(&mut contents)
89         .expect("unable to read kernel module content to buffer");
90     init_module(&contents, &CString::new("").unwrap()).expect("unable to load kernel module");
91 
92     delete_module(
93         &CString::new(kmod_name).unwrap(),
94         DeleteModuleFlags::empty(),
95     ).expect("unable to unload kernel module");
96 }
97 
98 #[test]
test_init_and_delete_module_with_params()99 fn test_init_and_delete_module_with_params() {
100     require_capability!("test_init_and_delete_module_with_params", CAP_SYS_MODULE);
101     let _m0 = crate::KMOD_MTX.lock();
102     let _m1 = crate::CWD_LOCK.read();
103 
104     let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
105 
106     let mut f = File::open(kmod_path).expect("unable to open kernel module");
107     let mut contents: Vec<u8> = Vec::new();
108     f.read_to_end(&mut contents)
109         .expect("unable to read kernel module content to buffer");
110     init_module(&contents, &CString::new("who=Nix number=2015").unwrap())
111         .expect("unable to load kernel module");
112 
113     delete_module(
114         &CString::new(kmod_name).unwrap(),
115         DeleteModuleFlags::empty(),
116     ).expect("unable to unload kernel module");
117 }
118 
119 #[test]
test_finit_module_invalid()120 fn test_finit_module_invalid() {
121     require_capability!("test_finit_module_invalid", CAP_SYS_MODULE);
122     let _m0 = crate::KMOD_MTX.lock();
123     let _m1 = crate::CWD_LOCK.read();
124 
125     let kmod_path = "/dev/zero";
126 
127     let f = File::open(kmod_path).expect("unable to open kernel module");
128     let result = finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty());
129 
130     assert_eq!(result.unwrap_err(), Errno::EINVAL);
131 }
132 
133 #[test]
test_finit_module_twice_and_delete_module()134 fn test_finit_module_twice_and_delete_module() {
135     require_capability!("test_finit_module_twice_and_delete_module", CAP_SYS_MODULE);
136     let _m0 = crate::KMOD_MTX.lock();
137     let _m1 = crate::CWD_LOCK.read();
138 
139     let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
140 
141     let f = File::open(kmod_path).expect("unable to open kernel module");
142     finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty())
143         .expect("unable to load kernel module");
144 
145     let result = finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty());
146 
147     assert_eq!(result.unwrap_err(), Errno::EEXIST);
148 
149     delete_module(
150         &CString::new(kmod_name).unwrap(),
151         DeleteModuleFlags::empty(),
152     ).expect("unable to unload kernel module");
153 }
154 
155 #[test]
test_delete_module_not_loaded()156 fn test_delete_module_not_loaded() {
157     require_capability!("test_delete_module_not_loaded", CAP_SYS_MODULE);
158     let _m0 = crate::KMOD_MTX.lock();
159     let _m1 = crate::CWD_LOCK.read();
160 
161     let result = delete_module(&CString::new("hello").unwrap(), DeleteModuleFlags::empty());
162 
163     assert_eq!(result.unwrap_err(), Errno::ENOENT);
164 }
165