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