Skip to content

Commit e77fc1d

Browse files
author
Gioh Kim
committed
ch04: remove proc entry when unloading the module
/ # insmod share/rust_proc.ko [ 7.874918] rust_proc: module verification failed: signature and/or required key missing - tainting kernel [ 7.876615] rust_proc: rust_proc is loaded [ 7.877263] rust_proc: succeeded to create a proc entry: 0xffff888005469300 / # ls proc/ 1 27 7 iomem pressure 10 28 8 ioports rust_demo 11 29 9 irq schedstat 111 3 bootconfig kallsyms self 12 30 buddyinfo kcore slabinfo 120 31 bus key-users softirqs 13 32 cgroups keys stat 14 33 cmdline kmsg swaps 15 34 consoles kpagecgroup sys 16 35 cpuinfo kpagecount sysrq-trigger 17 36 crypto kpageflags sysvipc 18 38 devices loadavg thread-self 19 4 diskstats locks timer_list 2 40 dma meminfo tty 20 41 driver misc uptime 21 42 dynamic_debug modules version 22 5 execdomains mounts vmallocinfo 23 53 fb mtrr vmstat 24 6 filesystems net zoneinfo 25 61 fs pagetypeinfo 26 62 interrupts partitions / # ls proc/rust_demo/ rust_proc_fs / # rmmod rust_proc [ 14.860586] rust_proc: rust_proc is unloaded / # ls proc/rust_demo/ ls: proc/rust_demo/: No such file or directory
1 parent f2eecb5 commit e77fc1d

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

rust/bindings/bindings_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <linux/uaccess.h>
3838
#include <linux/uio.h>
3939
#include <linux/proc_fs.h>
40+
#include <linux/seq_file.h>
4041

4142
/* `bindgen` gets confused at certain things. */
4243
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;

samples/rust/rust_proc.rs

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,49 @@ module! {
2525
license: "GPL",
2626
}
2727

28-
struct RustProc {}
28+
struct RustProc {
29+
parent: *mut bindings::proc_dir_entry,
30+
_entry: *mut bindings::proc_dir_entry,
31+
}
2932

3033
impl RustProc {
3134
unsafe extern "C" fn proc_open(
3235
_inode: *mut bindings::inode,
3336
_file: *mut bindings::file,
3437
) -> i32 {
38+
pr_info!("proc_open is invoked\n");
39+
pr_info!("proc_open is invoked\n");
40+
pr_info!("proc_open is invoked\n");
41+
pr_info!("proc_open is invoked\n");
42+
pr_info!("proc_open is invoked\n");
43+
pr_info!("proc_open is invoked\n");
44+
pr_info!("proc_open is invoked\n");
45+
pr_info!("proc_open is invoked\n");
46+
pr_info!("proc_open is invoked\n");
47+
pr_info!("proc_open is invoked\n");
48+
pr_info!("proc_open is invoked\n");
49+
pr_info!("proc_open is invoked\n");
50+
pr_info!("proc_open is invoked\n");
51+
pr_info!("proc_open is invoked\n");
52+
pr_info!("proc_open is invoked\n");
53+
pr_info!("proc_open is invoked\n");
54+
pr_info!("proc_open is invoked\n");
55+
pr_info!("proc_open is invoked\n");
56+
pr_info!("proc_open is invoked\n");
57+
pr_info!("proc_open is invoked\n");
58+
pr_info!("proc_open is invoked\n");
59+
pr_info!("proc_open is invoked\n");
60+
pr_info!("proc_open is invoked\n");
61+
62+
unsafe {
63+
let ret = bindings::single_open(_file, Some(Self::proc_show), ptr::null_mut());
64+
}
3565
0 as i32
3666
}
3767

38-
unsafe extern "C" fn proc_read(
39-
_file: *mut bindings::file,
40-
_buf: *mut core::ffi::c_char,
41-
_len: usize,
42-
_off: *mut bindings::loff_t,
43-
) -> isize {
44-
0 as isize
68+
unsafe extern "C" fn proc_show(_m: *mut bindings::seq_file, _v: *mut core::ffi::c_void) -> i32 {
69+
pr_info!("proc_read is invoked\n");
70+
0 as i32
4571
}
4672
}
4773

@@ -58,29 +84,43 @@ impl kernel::Module for RustProc {
5884
proc_get_unmapped_area: None, // mandatory to prevent build error
5985
proc_read_iter: None, // mandatory to prevent build error
6086
proc_open: Some(Self::proc_open),
61-
proc_read: Some(Self::proc_read),
87+
proc_read: None,
6288
proc_write: None,
6389
proc_lseek: None,
6490
proc_release: None,
6591
proc_poll: None,
6692
proc_ioctl: None,
6793
proc_mmap: None,
6894
};
95+
let entry_name = CString::try_from_fmt(fmt!("{}", PROC_FS_NAME))?;
96+
let entry: *mut bindings::proc_dir_entry =
97+
bindings::proc_create(entry_name.as_char_ptr(), 0o644, parent, &proc_ops);
98+
// How to check entry?
99+
if entry.is_null() {
100+
pr_info!("failed to create a proc entry\n");
101+
} else {
102+
pr_info!("succeeded to create a proc entry: {:p}\n", entry);
103+
}
69104

70-
bindings::proc_create(
71-
CString::try_from_fmt(fmt!("{}", PROC_FS_NAME))?.as_char_ptr(),
72-
0o644,
105+
Ok(RustProc {
73106
parent,
74-
&proc_ops,
75-
);
107+
_entry: entry,
108+
})
76109
}
77-
78-
Ok(RustProc {})
79110
}
80111
}
81112

82113
impl Drop for RustProc {
83114
fn drop(&mut self) {
115+
unsafe {
116+
let entry_name = CString::try_from_fmt(fmt!("{}", PROC_FS_NAME)).unwrap();
117+
bindings::remove_proc_entry(entry_name.as_char_ptr(), self.parent);
118+
119+
let dir_name = CString::try_from_fmt(fmt!("{}", SUB_DIR_NAME)).unwrap();
120+
bindings::remove_proc_entry(dir_name.as_char_ptr(), ptr::null_mut());
121+
}
84122
pr_info!("rust_proc is unloaded\n");
85123
}
86124
}
125+
126+
unsafe impl Sync for RustProc {}

0 commit comments

Comments
 (0)