Skip to content

Commit

Permalink
ch04: add more callback function
Browse files Browse the repository at this point in the history
At least it does not panic.
I checked the pointer of proc_open and proc_ops->proc_open value.
They are same. So I guess the function pointer setting is correct.

And I added messages to check if open function is crashed.
        for _ in 0..10000 {
            pr_err!("proc_open is invoked\n");
        }
Then I found out that the read generates crash as below.

/ # insmod share/rust_proc.ko
[    6.944654] rust_proc: module verification failed: signature and/or required key missing - tainting kernel
[    6.946329] rust_proc: rust_proc is loaded
[    6.946981] proc_create_data: rust_proc_fs proc_open=ffffffffc0201040
[    6.947959] rust_proc: succeeded to create a proc entry: 0xffff888005469780 proc_open=0xffffffffc0201040
/ # cat /proc/rust_demo/rust_proc_fs
.........
.........
[   15.546497] rust_proc: proc_open is invoked
[   15.546836] rust_proc: proc_open is invoked
[   15.547176] rust_proc: proc_open is invoked
[   15.547530] rust_proc: proc_open is invoked
[   15.547866] rust_proc: proc_open is invoked
[   15.548204] rust_proc: proc_open is invoked
[   15.548544] rust_proc: proc_open is invoked
[   15.549052] BUG: kernel NULL pointer dereference, address: 0000000000000001
[   15.549617] #PF: supervisor instruction fetch in kernel mode
[   15.549801] #PF: error_code(0x0010) - not-present page
[   15.549801] PGD 561e067 P4D 561e067 PUD 561c067 PMD 0
[   15.549801] Oops: 0010 [#1] PREEMPT SMP NOPTI
[   15.549801] CPU: 0 PID: 120 Comm: cat Tainted: G            E      6.3.0+ Rust-for-Linux#22
[   15.549801] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
[   15.549801] RIP: 0010:0x1
[   15.549801] Code: Unable to access opcode bytes at 0xffffffffffffffd7.
[   15.549801] RSP: 0018:ffff8880056b3e00 EFLAGS: 00010202
[   15.549801] RAX: ffff888005733898 RBX: 0000000000000000 RCX: ffff8880056b3ef0
[   15.549801] RDX: 0000000000001000 RSI: 00007ffc1f99b0a8 RDI: ffff888005729600
[   15.549801] RBP: ffff8880056b3e48 R08: 00007ffc1f99b0a8 R09: 0000000000000000
[   15.549801] R10: 0000000000000000 R11: 0000000000000001 R12: ffff888005469f00
[   15.549801] R13: ffff888005729600 R14: 0000000000000001 R15: 0000000000000000
[   15.549801] FS:  0000000001e153c0(0000) GS:ffff888007a00000(0000) knlGS:0000000000000000
[   15.549801] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   15.549801] CR2: ffffffffffffffd7 CR3: 0000000003c60000 CR4: 00000000000006f0
[   15.549801] Call Trace:
[   15.549801]  <TASK>
[   15.549801]  ? proc_reg_read+0xe8/0x150
[   15.549801]  vfs_read+0xb4/0x260
[   15.549801]  ? do_sendfile+0x1cf/0x3f0
[   15.549801]  ksys_read+0x5f/0xb0
[   15.549801]  __x64_sys_read+0x1b/0x20
[   15.549801]  do_syscall_64+0x35/0x50
[   15.549801]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[   15.549801] RIP: 0033:0x4ad272
[   15.549801] 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
[   15.549801] RSP: 002b:00007ffc1f99b048 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[   15.549801] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00000000004ad272
[   15.549801] RDX: 0000000000001000 RSI: 00007ffc1f99b0a8 RDI: 0000000000000003
[   15.549801] RBP: 00007ffc1f99b0a8 R08: 0000000000000001 R09: 0000000000000000
[   15.549801] R10: 0000000001000000 R11: 0000000000000246 R12: 0000000000001000
[   15.549801] R13: 0000000001e153a0 R14: 0000000000000000 R15: 0000000000000001
[   15.549801]  </TASK>
[   15.549801] Modules linked in: rust_proc(E)
[   15.549801] CR2: 0000000000000001
[   15.549801] ---[ end trace 0000000000000000 ]---
[   15.549801] RIP: 0010:0x1
[   15.549801] Code: Unable to access opcode bytes at 0xffffffffffffffd7.
[   15.549801] RSP: 0018:ffff8880056b3e00 EFLAGS: 00010202
[   15.549801] RAX: ffff888005733898 RBX: 0000000000000000 RCX: ffff8880056b3ef0
[   15.549801] RDX: 0000000000001000 RSI: 00007ffc1f99b0a8 RDI: ffff888005729600
[   15.549801] RBP: ffff8880056b3e48 R08: 00007ffc1f99b0a8 R09: 0000000000000000
[   15.549801] R10: 0000000000000000 R11: 0000000000000001 R12: ffff888005469f00
[   15.549801] R13: ffff888005729600 R14: 0000000000000001 R15: 0000000000000000
[   15.549801] FS:  0000000001e153c0(0000) GS:ffff888007a00000(0000) knlGS:0000000000000000
[   15.549801] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   15.549801] CR2: ffffffffffffffd7 CR3: 0000000003c60000 CR4: 00000000000006f0
[   15.549801] note: cat[120] exited with irqs disabled
[   15.572950] BUG: kernel NULL pointer dereference, address: 0000000000000001
[   15.573491] #PF: supervisor instruction fetch in kernel mode
[   15.573932] #PF: error_code(0x0010) - not-present page
[   15.574335] PGD 0 P4D 0
[   15.574535] Oops: 0010 [#2] PREEMPT SMP NOPTI
[   15.574892] CPU: 0 PID: 120 Comm: cat Tainted: G      D     E      6.3.0+ Rust-for-Linux#22
[   15.575462] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
[   15.576107] RIP: 0010:0x1
[   15.576328] Code: Unable to access opcode bytes at 0xffffffffffffffd7.
[   15.576842] RSP: 0018:ffff8880056b3de8 EFLAGS: 00010246
[   15.576842] RAX: ffff888005733898 RBX: 0000000000000000 RCX: 0000000000000001
[   15.576842] RDX: ffff8880054ec800 RSI: ffff888005729600 RDI: ffff888004f7ce08
[   15.576842] RBP: ffff8880056b3e30 R08: ffff888003c43c00 R09: ffff888004f7ce08
[   15.576842] R10: ffffea00000f93c0 R11: 0000000000000001 R12: ffff8880056bae10
[   15.576842] R13: 00000000000a800d R14: ffff888005469f00 R15: ffff888005469f18
[   15.576842] FS:  0000000000000000(0000) GS:ffff888007a00000(0000) knlGS:0000000000000000
[   15.576842] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   15.576842] CR2: ffffffffffffffd7 CR3: 0000000002434000 CR4: 00000000000006f0
[   15.576842] Call Trace:
[   15.576842]  <TASK>
[   15.576842]  ? close_pdeo+0x59/0x120
[   15.576842]  proc_reg_release+0x6f/0x80
[   15.576842]  __fput+0xf0/0x220
[   15.576842]  ____fput+0xe/0x10
[   15.576842]  task_work_run+0xc3/0xe0
[   15.576842]  do_exit+0x3e2/0xab0
[   15.576842]  make_task_dead+0x83/0x130
[   15.576842]  rewind_stack_and_make_dead+0x17/0x20
[   15.576842] RIP: 0033:0x4ad272
[   15.576842] Code: Unable to access opcode bytes at 0x4ad248.
[   15.576842] RSP: 002b:00007ffc1f99b048 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[   15.576842] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00000000004ad272
[   15.576842] RDX: 0000000000001000 RSI: 00007ffc1f99b0a8 RDI: 0000000000000003
[   15.576842] RBP: 00007ffc1f99b0a8 R08: 0000000000000001 R09: 0000000000000000
[   15.576842] R10: 0000000001000000 R11: 0000000000000246 R12: 0000000000001000
[   15.576842] R13: 0000000001e153a0 R14: 0000000000000000 R15: 0000000000000001
[   15.576842]  </TASK>
[   15.576842] Modules linked in: rust_proc(E)
[   15.576842] CR2: 0000000000000001
[   15.576842] ---[ end trace 0000000000000000 ]---
[   15.576842] RIP: 0010:0x1
[   15.576842] Code: Unable to access opcode bytes at 0xffffffffffffffd7.
[   15.576842] RSP: 0018:ffff8880056b3e00 EFLAGS: 00010202
[   15.576842] RAX: ffff888005733898 RBX: 0000000000000000 RCX: ffff8880056b3ef0
[   15.576842] RDX: 0000000000001000 RSI: 00007ffc1f99b0a8 RDI: ffff888005729600
[   15.576842] RBP: ffff8880056b3e48 R08: 00007ffc1f99b0a8 R09: 0000000000000000
[   15.576842] R10: 0000000000000000 R11: 0000000000000001 R12: ffff888005469f00
[   15.576842] R13: ffff888005729600 R14: 0000000000000001 R15: 0000000000000000
[   15.576842] FS:  0000000000000000(0000) GS:ffff888007a00000(0000) knlGS:0000000000000000
[   15.576842] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   15.576842] CR2: ffffffffffffffd7 CR3: 0000000002434000 CR4: 00000000000006f0
[   15.576842] note: cat[120] exited with irqs disabled
[   15.595880] Fixing recursive fault but reboot is needed!
[   15.596287] BUG: scheduling while atomic: cat/120/0x00000000
[   15.596720] Modules linked in: rust_proc(E)
[   15.597039] CPU: 0 PID: 120 Comm: cat Tainted: G      D     E      6.3.0+ Rust-for-Linux#22
[   15.597587] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
[   15.598226] Call Trace:
[   15.598420]  <TASK>
[   15.598592]  dump_stack_lvl+0x58/0x70
[   15.598883]  dump_stack+0x10/0x20
[   15.599141]  __schedule_bug+0x62/0x70
[   15.599449]  __schedule+0x838/0x1450
[   15.599731]  ? vprintk_default+0x1d/0x20
[   15.599849]  ? vprintk+0x60/0x80
[   15.599849]  ? _printk+0x4b/0x50
[   15.599849]  do_task_dead+0x41/0x50
[   15.599849]  make_task_dead+0x129/0x130
[   15.599849]  rewind_stack_and_make_dead+0x17/0x20
[   15.599849] RIP: 0033:0x4ad272
[   15.599849] Code: Unable to access opcode bytes at 0x4ad248.
[   15.599849] RSP: 002b:00007ffc1f99b048 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[   15.599849] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00000000004ad272
[   15.599849] RDX: 0000000000001000 RSI: 00007ffc1f99b0a8 RDI: 0000000000000003
[   15.599849] RBP: 00007ffc1f99b0a8 R08: 0000000000000001 R09: 0000000000000000
[   15.599849] R10: 0000000001000000 R11: 0000000000000246 R12: 0000000000001000
[   15.599849] R13: 0000000001e153a0 R14: 0000000000000000 R15: 0000000000000001
[   15.599849]  </TASK>

diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 8379593fa4bb..bea879760ebc 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -573,7 +573,8 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
        p = proc_create_reg(name, mode, &parent, data);
        if (!p)
                return NULL;
-       p->proc_ops = proc_ops;
+       printk(KERN_ERR "proc_create_data: %s proc_open=%px\n", name, proc_ops->proc_open);
+       p->proc_ops = proc_ops;
        pde_set_flags(p);
        return proc_register(parent, p);
 }
  • Loading branch information
Gioh Kim authored and gurugio committed Oct 14, 2023
1 parent 91f519c commit f88eeee
Showing 1 changed file with 28 additions and 8 deletions.
36 changes: 28 additions & 8 deletions samples/rust/rust_proc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ impl RustProc {
pr_err!("proc_open is invoked\n");
pr_err!("proc_open is invoked\n");

while true {
pr_info!("proc_open is invoked\n");
}

unsafe {
let ret = bindings::single_open(_file, Some(Self::proc_show), ptr::null_mut());
}
Expand All @@ -74,6 +70,26 @@ impl RustProc {

unsafe extern "C" fn proc_show(_m: *mut bindings::seq_file, _v: *mut core::ffi::c_void) -> i32 {
pr_info!("proc_read is invoked\n");
unsafe {
bindings::seq_printf(
_m,
CString::try_from_fmt(fmt!("Hello, world!\n"))
.unwrap()
.as_char_ptr(),
);
}
0 as i32
}

unsafe extern "C" fn proc_release(
_inode: *mut bindings::inode,
_file: *mut bindings::file,
) -> i32 {
pr_info!("proc_release is invoked\n");
unsafe {
let ret = bindings::single_release(_inode, _file);
}
// single_release(_inode, _file);
0 as i32
}
}
Expand All @@ -93,10 +109,10 @@ impl kernel::Module for RustProc {
proc_get_unmapped_area: None, // mandatory to prevent build error
proc_read_iter: None, // mandatory to prevent build error
proc_open: Some(Self::proc_open),
proc_read: None,
proc_read: Some(bindings::seq_read),
proc_write: None,
proc_lseek: None,
proc_release: None,
proc_lseek: Some(bindings::seq_lseek),
proc_release: Some(Self::proc_release),
proc_poll: None,
proc_ioctl: None,
proc_mmap: None,
Expand All @@ -112,7 +128,11 @@ impl kernel::Module for RustProc {
if entry.is_null() {
pr_info!("failed to create a proc entry\n");
} else {
pr_info!("succeeded to create a proc entry: {:p}\n", entry);
pr_info!(
"succeeded to create a proc entry: {:p} proc_open={:#x}\n",
entry,
Self::proc_open as usize
);
}

Ok(ret)
Expand Down

0 comments on commit f88eeee

Please sign in to comment.