nix/
kmod.rs

1//! Load and unload kernel modules.
2//!
3//! For more details see
4
5use std::ffi::CStr;
6use std::os::unix::io::AsRawFd;
7
8use crate::errno::Errno;
9use crate::Result;
10
11/// Loads a kernel module from a buffer.
12///
13/// It loads an ELF image into kernel space,
14/// performs any necessary symbol relocations,
15/// initializes module parameters to values provided by the caller,
16/// and then runs the module's init function.
17///
18/// This function requires `CAP_SYS_MODULE` privilege.
19///
20/// The `module_image` argument points to a buffer containing the binary image
21/// to be loaded. The buffer should contain a valid ELF image
22/// built for the running kernel.
23///
24/// The `param_values` argument is a string containing space-delimited specifications
25/// of the values for module parameters.
26/// Each of the parameter specifications has the form:
27///
28/// `name[=value[,value...]]`
29///
30/// # Example
31///
32/// ```no_run
33/// use std::fs::File;
34/// use std::io::Read;
35/// use std::ffi::CString;
36/// use nix::kmod::init_module;
37///
38/// let mut f = File::open("mykernel.ko").unwrap();
39/// let mut contents: Vec<u8> = Vec::new();
40/// f.read_to_end(&mut contents).unwrap();
41/// init_module(&mut contents, &CString::new("who=Rust when=Now,12").unwrap()).unwrap();
42/// ```
43///
44/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
45pub fn init_module(module_image: &[u8], param_values: &CStr) -> Result<()> {
46    let res = unsafe {
47        libc::syscall(
48            libc::SYS_init_module,
49            module_image.as_ptr(),
50            module_image.len(),
51            param_values.as_ptr(),
52        )
53    };
54
55    Errno::result(res).map(drop)
56}
57
58libc_bitflags!(
59    /// Flags used by the `finit_module` function.
60    pub struct ModuleInitFlags: libc::c_uint {
61        /// Ignore symbol version hashes.
62        MODULE_INIT_IGNORE_MODVERSIONS;
63        /// Ignore kernel version magic.
64        MODULE_INIT_IGNORE_VERMAGIC;
65    }
66);
67
68/// Loads a kernel module from a given file descriptor.
69///
70/// # Example
71///
72/// ```no_run
73/// use std::fs::File;
74/// use std::ffi::CString;
75/// use nix::kmod::{finit_module, ModuleInitFlags};
76///
77/// let f = File::open("mymod.ko").unwrap();
78/// finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()).unwrap();
79/// ```
80///
81/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
82pub fn finit_module<T: AsRawFd>(
83    fd: &T,
84    param_values: &CStr,
85    flags: ModuleInitFlags,
86) -> Result<()> {
87    let res = unsafe {
88        libc::syscall(
89            libc::SYS_finit_module,
90            fd.as_raw_fd(),
91            param_values.as_ptr(),
92            flags.bits(),
93        )
94    };
95
96    Errno::result(res).map(drop)
97}
98
99libc_bitflags!(
100    /// Flags used by `delete_module`.
101    ///
102    /// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html)
103    /// for a detailed description how these flags work.
104    pub struct DeleteModuleFlags: libc::c_int {
105        O_NONBLOCK;
106        O_TRUNC;
107    }
108);
109
110/// Unloads the kernel module with the given name.
111///
112/// # Example
113///
114/// ```no_run
115/// use std::ffi::CString;
116/// use nix::kmod::{delete_module, DeleteModuleFlags};
117///
118/// delete_module(&CString::new("mymod").unwrap(), DeleteModuleFlags::O_NONBLOCK).unwrap();
119/// ```
120///
121/// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html) for more information.
122pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> {
123    let res = unsafe {
124        libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits())
125    };
126
127    Errno::result(res).map(drop)
128}