Skip to content

Commit 970ab72

Browse files
author
Gioh Kim
committed
ch04: kernel panic when openning
proc_create returns non-null pointer but open generates null-pointer panic. I checked the panic address. That is a code calling open. / # insmod share/rust_proc.ko [ 22.202776] rust_proc: module verification failed: signature and/or required key missing - tainting kernel [ 22.204453] rust_proc: rust_proc is loaded [ 22.205103] rust_proc: succeeded to create a proc entry: 0xffff8880054696c0 / # cat /proc/rust_demo/rust_proc_fs [ 26.663960] kernel tried to execute NX-protected page - exploit attempt? (uid: 0) [ 26.665132] BUG: unable to handle page fault for address: ffff888005492a00 [ 26.666141] #PF: supervisor instruction fetch in kernel mode [ 26.666674] #PF: error_code(0x0011) - permissions violation [ 26.666674] PGD 3a01067 P4D 3a01067 PUD 3a02067 PMD 80000000054001e3 [ 26.666674] Oops: 0011 [#1] PREEMPT SMP NOPTI [ 26.666674] CPU: 0 PID: 120 Comm: cat Tainted: G E 6.3.0+ Rust-for-Linux#18 [ 26.666674] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 [ 26.666674] RIP: 0010:0xffff888005492a00 [ 26.666674] Code: 00 00 60 11 e0 81 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 [ 26.666674] RSP: 0018:ffff8880056c7e00 EFLAGS: 00010286 [ 26.666674] RAX: ffff8880056c7918 RBX: 0000000000000000 RCX: ffff8880056c7ef0 [ 26.666674] RDX: 0000000000001000 RSI: 00007ffc8b3ba048 RDI: ffff888005721400 [ 26.666674] RBP: ffff8880056c7e48 R08: 00007ffc8b3ba048 R09: 0000000000000000 [ 26.666674] R10: 0000000000000000 R11: ffff888005492a00 R12: ffff8880054696c0 [ 26.666674] R13: ffff888005721400 R14: 0000000000000001 R15: 0000000000000000 [ 26.666674] FS: 000000000249a3c0(0000) GS:ffff888007a00000(0000) knlGS:0000000000000000 [ 26.666674] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 26.666674] CR2: ffff888005492a00 CR3: 00000000054c6000 CR4: 00000000000006f0 [ 26.666674] Call Trace: [ 26.666674] <TASK> [ 26.666674] ? proc_reg_read+0xe8/0x150 [ 26.666674] vfs_read+0xb4/0x260 [ 26.666674] ? do_sendfile+0x1cf/0x3f0 [ 26.666674] ksys_read+0x5f/0xb0 [ 26.666674] __x64_sys_read+0x1b/0x20 [ 26.666674] do_syscall_64+0x35/0x50 [ 26.666674] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 26.666674] RIP: 0033:0x4ad272 [ 26.666674] Code: 31 c0 e9 b1 fe ff ff 50 48 8d 3d c1 80 17 00 e8 54 8e 00 00 0f 1f 40 00 f3 0f 1e fa 64 8b 04 25 18 00 00 04 [ 26.666674] RSP: 002b:00007ffc8b3b9fe8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 [ 26.666674] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00000000004ad272 [ 26.666674] RDX: 0000000000001000 RSI: 00007ffc8b3ba048 RDI: 0000000000000003 [ 26.666674] RBP: 00007ffc8b3ba048 R08: 0000000000000001 R09: 0000000000000000 [ 26.666674] R10: 0000000001000000 R11: 0000000000000246 R12: 0000000000001000 [ 26.666674] R13: 000000000249a3a0 R14: 0000000000000000 R15: 0000000000000001 [ 26.666674] </TASK> [ 26.666674] Modules linked in: rust_proc(E) [ 26.666674] CR2: ffff888005492a00 [ 26.666674] ---[ end trace 0000000000000000 ]--- [ 26.666674] RIP: 0010:0xffff888005492a00 [ 26.666674] Code: 00 00 60 11 e0 81 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 [ 26.666674] RSP: 0018:ffff8880056c7e00 EFLAGS: 00010286 [ 26.666674] RAX: ffff8880056c7918 RBX: 0000000000000000 RCX: ffff8880056c7ef0 [ 26.666674] RDX: 0000000000001000 RSI: 00007ffc8b3ba048 RDI: ffff888005721400 [ 26.666674] RBP: ffff8880056c7e48 R08: 00007ffc8b3ba048 R09: 0000000000000000 [ 26.666674] R10: 0000000000000000 R11: ffff888005492a00 R12: ffff8880054696c0 [ 26.666674] R13: ffff888005721400 R14: 0000000000000001 R15: 0000000000000000 [ 26.666674] FS: 000000000249a3c0(0000) GS:ffff888007a00000(0000) knlGS:0000000000000000 [ 26.666674] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 26.666674] CR2: ffff888005492a00 CR3: 00000000054c6000 CR4: 00000000000006f0 [ 26.666674] note: cat[120] exited with irqs disabled Killed
1 parent e77fc1d commit 970ab72

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

samples/rust/rust_proc.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//! make LLVM=1 M=samples/rust
88
99
// core is from Rust compiler, not from kernel
10+
use core::marker::PhantomPinned;
1011
use core::ptr;
1112

1213
use kernel::bindings;
@@ -26,8 +27,10 @@ module! {
2627
}
2728

2829
struct RustProc {
30+
ops: bindings::proc_ops,
2931
parent: *mut bindings::proc_dir_entry,
3032
_entry: *mut bindings::proc_dir_entry,
33+
_pin: PhantomPinned,
3134
}
3235

3336
impl RustProc {
@@ -55,9 +58,13 @@ impl RustProc {
5558
pr_info!("proc_open is invoked\n");
5659
pr_info!("proc_open is invoked\n");
5760
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+
pr_err!("proc_open is invoked\n");
62+
pr_err!("proc_open is invoked\n");
63+
pr_err!("proc_open is invoked\n");
64+
65+
while true {
66+
pr_info!("proc_open is invoked\n");
67+
}
6168

6269
unsafe {
6370
let ret = bindings::single_open(_file, Some(Self::proc_show), ptr::null_mut());
@@ -79,33 +86,36 @@ impl kernel::Module for RustProc {
7986
let dir_name = CString::try_from_fmt(fmt!("{}", SUB_DIR_NAME))?;
8087
let parent = bindings::proc_mkdir(dir_name.as_char_ptr(), ptr::null_mut());
8188

82-
let proc_ops = bindings::proc_ops {
83-
proc_flags: 0, // mandatory to prevent build error
84-
proc_get_unmapped_area: None, // mandatory to prevent build error
85-
proc_read_iter: None, // mandatory to prevent build error
86-
proc_open: Some(Self::proc_open),
87-
proc_read: None,
88-
proc_write: None,
89-
proc_lseek: None,
90-
proc_release: None,
91-
proc_poll: None,
92-
proc_ioctl: None,
93-
proc_mmap: None,
89+
let ret = Self {
90+
parent,
91+
ops: bindings::proc_ops {
92+
proc_flags: 0, // mandatory to prevent build error
93+
proc_get_unmapped_area: None, // mandatory to prevent build error
94+
proc_read_iter: None, // mandatory to prevent build error
95+
proc_open: Some(Self::proc_open),
96+
proc_read: None,
97+
proc_write: None,
98+
proc_lseek: None,
99+
proc_release: None,
100+
proc_poll: None,
101+
proc_ioctl: None,
102+
proc_mmap: None,
103+
},
104+
_entry: ptr::null_mut(),
105+
_pin: PhantomPinned,
94106
};
107+
95108
let entry_name = CString::try_from_fmt(fmt!("{}", PROC_FS_NAME))?;
96109
let entry: *mut bindings::proc_dir_entry =
97-
bindings::proc_create(entry_name.as_char_ptr(), 0o644, parent, &proc_ops);
110+
bindings::proc_create(entry_name.as_char_ptr(), 0o644, parent, &ret.ops);
98111
// How to check entry?
99112
if entry.is_null() {
100113
pr_info!("failed to create a proc entry\n");
101114
} else {
102115
pr_info!("succeeded to create a proc entry: {:p}\n", entry);
103116
}
104117

105-
Ok(RustProc {
106-
parent,
107-
_entry: entry,
108-
})
118+
Ok(ret)
109119
}
110120
}
111121
}

0 commit comments

Comments
 (0)