Skip to content

Commit

Permalink
Avoid strlen by assigning explicit length of string for proc_read (#18)
Browse files Browse the repository at this point in the history
Since the address of buffer is userspace address, it may trigger an unexpected fault on strlen(buffer).

On Ubuntu 20.04.2 LTS ( 5.8.0-63-generic ), using strlen(buffer) will result in the following:
[ 2168.010930] /proc/buffer1k created
[ 2177.014347] BUG: unable to handle page fault for address: 00007fbbc2a17000
[ 2177.014355] #PF: supervisor read access in kernel mode
[ 2177.014358] #PF: error_code(0x0000) - not-present page
[ 2177.014361] PGD 80000003c61d0067 P4D 80000003c61d0067 PUD 3ee6c5067 PMD 40e1ff067 PTE 0
[ 2177.014369] Oops: 0000 [#1] SMP PTI
[ 2177.014376] CPU: 7 PID: 4750 Comm: cat Tainted: P        W  OE     5.8.0-63-generic #71~20.04.1-Ubuntu

[ 2177.014387] RIP: 0010:procfile_read+0xb/0x20 [procfs2]
[ 2177.014393] Code: Unable to access opcode bytes at RIP 0xffffffffc1253fe1.
[ 2177.014396] RSP: 0018:ffffbc84412cbe78 EFLAGS: 00010286
[ 2177.014400] RAX: ffffffffc1254000 RBX: 0000000000020000 RCX: ffffbc84412cbef0
[ 2177.014403] RDX: 0000000000020000 RSI: 00007fbbc2a17000 RDI: ffffa057d2708f00
[ 2177.014406] RBP: ffffbc84412cbe80 R08: 0000000000000001 R09: 0000000000000000
[ 2177.014409] R10: 0000000000000000 R11: 0000000000000000 R12: ffffa0581de8ccc0
[ 2177.014411] R13: ffffa057d2708f00 R14: ffffbc84412cbef0 R15: 00007fbbc2a17000
[ 2177.014415] FS:  00007fbbc3bfa580(0000) GS:ffffa0582dbc0000(0000) knlGS:0000000000000000
[ 2177.014418] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2177.014421] CR2: ffffffffc1253fe1 CR3: 00000003c611c004 CR4: 00000000003606e0
[ 2177.014424] Call Trace:
[ 2177.014435]  proc_reg_read+0x66/0x90
[ 2177.014441]  vfs_read+0xaa/0x190
[ 2177.014446]  ksys_read+0x67/0xe0
[ 2177.014451]  __x64_sys_read+0x1a/0x20
[ 2177.014458]  do_syscall_64+0x49/0xc0
[ 2177.014464]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 2177.014467] RIP: 0033:0x7fbbc3b18142
[ 2177.014472] Code: c0 e9 c2 fe ff ff 50 48 8d 3d 3a ca 0a 00 e8 f5 19 02 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24
[ 2177.014476] RSP: 002b:00007ffcf2d20d78 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[ 2177.014479] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fbbc3b18142
[ 2177.014482] RDX: 0000000000020000 RSI: 00007fbbc2a17000 RDI: 0000000000000003
[ 2177.014485] RBP: 00007fbbc2a17000 R08: 00007fbbc2a16010 R09: 0000000000000000
[ 2177.014487] R10: 0000000000000022 R11: 0000000000000246 R12: 0000560f8ff081f0
[ 2177.014490] R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000

[ 2177.014635] CR2: 00007fbbc2a17000
[ 2177.014639] ---[ end trace b71ff05c1b0a10f6 ]---
[ 2177.184174] RIP: 0010:procfile_read+0xb/0x20 [procfs2]
[ 2177.184176] Code: Unable to access opcode bytes at RIP 0xffffffffc1253fe1.
[ 2177.184177] RSP: 0018:ffffbc84412cbe78 EFLAGS: 00010286
[ 2177.184178] RAX: ffffffffc1254000 RBX: 0000000000020000 RCX: ffffbc84412cbef0
[ 2177.184179] RDX: 0000000000020000 RSI: 00007fbbc2a17000 RDI: ffffa057d2708f00
[ 2177.184180] RBP: ffffbc84412cbe80 R08: 0000000000000001 R09: 0000000000000000
[ 2177.184180] R10: 0000000000000000 R11: 0000000000000000 R12: ffffa0581de8ccc0
[ 2177.184181] R13: ffffa057d2708f00 R14: ffffbc84412cbef0 R15: 00007fbbc2a17000
[ 2177.184182] FS:  00007fbbc3bfa580(0000) GS:ffffa0582dbc0000(0000) knlGS:0000000000000000
[ 2177.184182] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2177.184183] CR2: ffffffffc1253fe1 CR3: 00000003c611c004 CR4: 00000000003606e0
  • Loading branch information
linD026 authored Jul 29, 2021
1 parent a82cf74 commit c7a7a66
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
15 changes: 11 additions & 4 deletions examples/procfs1.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,19 @@ ssize_t procfile_read(struct file *filePointer,
size_t buffer_length,
loff_t *offset)
{
int ret = 0;
if (strlen(buffer) == 0) {
char s[13] = "HelloWorld!\n";
int len = sizeof(s);
ssize_t ret = len;

if (*offset >= len || copy_to_user(buffer, s, len)) {
pr_info("copy_to_user failed\n");
ret = 0;
}
else {
pr_info("procfile read %s\n", filePointer->f_path.dentry->d_name.name);
ret = copy_to_user(buffer, "HelloWorld!\n", sizeof("HelloWorld!\n"));
ret = sizeof("HelloWorld!\n");
*offset += len;
}

return ret;
}

Expand Down
15 changes: 11 additions & 4 deletions examples/procfs2.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,19 @@ ssize_t procfile_read(struct file *filePointer,
size_t buffer_length,
loff_t *offset)
{
int ret = 0;
if (strlen(buffer) == 0) {
char s[13] = "HelloWorld!\n";
int len = sizeof(s);
ssize_t ret = len;

if (*offset >= len || copy_to_user(buffer, s, len)) {
pr_info("copy_to_user failed\n");
ret = 0;
}
else {
pr_info("procfile read %s\n", filePointer->f_path.dentry->d_name.name);
ret = copy_to_user(buffer, "HelloWorld!\n", sizeof("HelloWorld!\n"));
ret = sizeof("HelloWorld!\n");
*offset += len;
}

return ret;
}

Expand Down

0 comments on commit c7a7a66

Please sign in to comment.