The userspace can ask kprobe to intercept strings at any memory address, including invalid kernel address. In this case, fetch_store_strlen() would crash since it uses general usercopy function.
For example, we can crash the kernel by doing something as below:
$ sudo kprobe 'p:do_sys_open +0(+0(%si)):string'
[ 103.620391] BUG: GPF in non-whitelisted uaccess (non-canonical address?) [ 103.622104] general protection fault: 0000 [#1] SMP PTI [ 103.623424] CPU: 10 PID: 1046 Comm: cat Not tainted 5.0.0-rc3-00130-gd73aba1-dirty #96 [ 103.625321] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-2-g628b2e6-dirty-20190104_103505-linux 04/01/2014 [ 103.628284] RIP: 0010:process_fetch_insn+0x1ab/0x4b0 [ 103.629518] Code: 10 83 80 28 2e 00 00 01 31 d2 31 ff 48 8b 74 24 28 eb 0c 81 fa ff 0f 00 00 7f 1c 85 c0 75 18 66 66 90 0f ae e8 48 63 ca 89 f8 <8a> 0c 31 66 66 90 83 c2 01 84 c9 75 dc 89 54 24 34 89 44 24 28 48 [ 103.634032] RSP: 0018:ffff88845eb37ce0 EFLAGS: 00010246 [ 103.635312] RAX: 0000000000000000 RBX: ffff888456c4e5a8 RCX: 0000000000000000 [ 103.637057] RDX: 0000000000000000 RSI: 2e646c2f6374652f RDI: 0000000000000000 [ 103.638795] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 [ 103.640556] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 103.642297] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 103.644040] FS: 0000000000000000(0000) GS:ffff88846f000000(0000) knlGS:0000000000000000 [ 103.646019] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 103.647436] CR2: 00007ffc79758038 CR3: 0000000463360006 CR4: 0000000000020ee0 [ 103.649147] Call Trace: [ 103.649781] ? sched_clock_cpu+0xc/0xa0 [ 103.650747] ? do_sys_open+0x5/0x220 [ 103.651635] kprobe_trace_func+0x303/0x380 [ 103.652645] ? do_sys_open+0x5/0x220 [ 103.653528] kprobe_dispatcher+0x45/0x50 [ 103.654682] ? do_sys_open+0x1/0x220 [ 103.655875] kprobe_ftrace_handler+0x90/0xf0 [ 103.657282] ftrace_ops_assist_func+0x54/0xf0 [ 103.658564] ? __call_rcu+0x1dc/0x280 [ 103.659482] 0xffffffffc00000bf [ 103.660384] ? __ia32_sys_open+0x20/0x20 [ 103.661682] ? do_sys_open+0x1/0x220 [ 103.662863] do_sys_open+0x5/0x220 [ 103.663988] do_syscall_64+0x60/0x210 [ 103.665201] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 103.666862] RIP: 0033:0x7fc22fadccdd [ 103.668034] Code: 48 89 54 24 e0 41 83 e2 40 75 32 89 f0 25 00 00 41 00 3d 00 00 41 00 74 24 89 f2 b8 01 01 00 00 48 89 fe bf 9c ff ff ff 0f 05 <48> 3d 00 f0 ff ff 77 33 f3 c3 66 0f 1f 84 00 00 00 00 00 48 8d 44 [ 103.674029] RSP: 002b:00007ffc7972c3a8 EFLAGS: 00000287 ORIG_RAX: 0000000000000101 [ 103.676512] RAX: ffffffffffffffda RBX: 0000562f86147a21 RCX: 00007fc22fadccdd [ 103.678853] RDX: 0000000000080000 RSI: 00007fc22fae1428 RDI: 00000000ffffff9c [ 103.681151] RBP: ffffffffffffffff R08: 0000000000000000 R09: 0000000000000000 [ 103.683489] R10: 0000000000000000 R11: 0000000000000287 R12: 00007fc22fce90a8 [ 103.685774] R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000000 [ 103.688056] Modules linked in: [ 103.689131] ---[ end trace 43792035c28984a1 ]---
This can be fixed by using probe_mem_read() instead.
Signed-off-by: Changbin Du changbin.du@gmail.com Cc: stable@vger.kernel.org --- kernel/trace/trace_kprobe.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index d5fb09ebba8b..9eaf07f99212 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -861,22 +861,14 @@ static const struct file_operations kprobe_profile_ops = { static nokprobe_inline int fetch_store_strlen(unsigned long addr) { - mm_segment_t old_fs; int ret, len = 0; u8 c;
- old_fs = get_fs(); - set_fs(KERNEL_DS); - pagefault_disable(); - do { - ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1); + ret = probe_mem_read(&c, (u8 *)addr + len, 1); len++; } while (c && ret == 0 && len < MAX_STRING_SIZE);
- pagefault_enable(); - set_fs(old_fs); - return (ret < 0) ? ret : len; }
Hi Steven, I think this is a critical issue. Could you give priority to this fix?
On Fri, Jan 25, 2019 at 11:10:50PM +0800, Changbin Du wrote:
The userspace can ask kprobe to intercept strings at any memory address, including invalid kernel address. In this case, fetch_store_strlen() would crash since it uses general usercopy function.
For example, we can crash the kernel by doing something as below:
$ sudo kprobe 'p:do_sys_open +0(+0(%si)):string'
[ 103.620391] BUG: GPF in non-whitelisted uaccess (non-canonical address?) [ 103.622104] general protection fault: 0000 [#1] SMP PTI [ 103.623424] CPU: 10 PID: 1046 Comm: cat Not tainted 5.0.0-rc3-00130-gd73aba1-dirty #96 [ 103.625321] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-2-g628b2e6-dirty-20190104_103505-linux 04/01/2014 [ 103.628284] RIP: 0010:process_fetch_insn+0x1ab/0x4b0 [ 103.629518] Code: 10 83 80 28 2e 00 00 01 31 d2 31 ff 48 8b 74 24 28 eb 0c 81 fa ff 0f 00 00 7f 1c 85 c0 75 18 66 66 90 0f ae e8 48 63 ca 89 f8 <8a> 0c 31 66 66 90 83 c2 01 84 c9 75 dc 89 54 24 34 89 44 24 28 48 [ 103.634032] RSP: 0018:ffff88845eb37ce0 EFLAGS: 00010246 [ 103.635312] RAX: 0000000000000000 RBX: ffff888456c4e5a8 RCX: 0000000000000000 [ 103.637057] RDX: 0000000000000000 RSI: 2e646c2f6374652f RDI: 0000000000000000 [ 103.638795] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 [ 103.640556] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 103.642297] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 103.644040] FS: 0000000000000000(0000) GS:ffff88846f000000(0000) knlGS:0000000000000000 [ 103.646019] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 103.647436] CR2: 00007ffc79758038 CR3: 0000000463360006 CR4: 0000000000020ee0 [ 103.649147] Call Trace: [ 103.649781] ? sched_clock_cpu+0xc/0xa0 [ 103.650747] ? do_sys_open+0x5/0x220 [ 103.651635] kprobe_trace_func+0x303/0x380 [ 103.652645] ? do_sys_open+0x5/0x220 [ 103.653528] kprobe_dispatcher+0x45/0x50 [ 103.654682] ? do_sys_open+0x1/0x220 [ 103.655875] kprobe_ftrace_handler+0x90/0xf0 [ 103.657282] ftrace_ops_assist_func+0x54/0xf0 [ 103.658564] ? __call_rcu+0x1dc/0x280 [ 103.659482] 0xffffffffc00000bf [ 103.660384] ? __ia32_sys_open+0x20/0x20 [ 103.661682] ? do_sys_open+0x1/0x220 [ 103.662863] do_sys_open+0x5/0x220 [ 103.663988] do_syscall_64+0x60/0x210 [ 103.665201] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 103.666862] RIP: 0033:0x7fc22fadccdd [ 103.668034] Code: 48 89 54 24 e0 41 83 e2 40 75 32 89 f0 25 00 00 41 00 3d 00 00 41 00 74 24 89 f2 b8 01 01 00 00 48 89 fe bf 9c ff ff ff 0f 05 <48> 3d 00 f0 ff ff 77 33 f3 c3 66 0f 1f 84 00 00 00 00 00 48 8d 44 [ 103.674029] RSP: 002b:00007ffc7972c3a8 EFLAGS: 00000287 ORIG_RAX: 0000000000000101 [ 103.676512] RAX: ffffffffffffffda RBX: 0000562f86147a21 RCX: 00007fc22fadccdd [ 103.678853] RDX: 0000000000080000 RSI: 00007fc22fae1428 RDI: 00000000ffffff9c [ 103.681151] RBP: ffffffffffffffff R08: 0000000000000000 R09: 0000000000000000 [ 103.683489] R10: 0000000000000000 R11: 0000000000000287 R12: 00007fc22fce90a8 [ 103.685774] R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000000 [ 103.688056] Modules linked in: [ 103.689131] ---[ end trace 43792035c28984a1 ]---
This can be fixed by using probe_mem_read() instead.
Signed-off-by: Changbin Du changbin.du@gmail.com Cc: stable@vger.kernel.org
kernel/trace/trace_kprobe.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index d5fb09ebba8b..9eaf07f99212 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -861,22 +861,14 @@ static const struct file_operations kprobe_profile_ops = { static nokprobe_inline int fetch_store_strlen(unsigned long addr) {
- mm_segment_t old_fs; int ret, len = 0; u8 c;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- pagefault_disable();
- do {
ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
len++; } while (c && ret == 0 && len < MAX_STRING_SIZE);ret = probe_mem_read(&c, (u8 *)addr + len, 1);
- pagefault_enable();
- set_fs(old_fs);
- return (ret < 0) ? ret : len;
} -- 2.19.1
On Wed, 13 Feb 2019 22:36:40 +0800 Changbin Du changbin.du@gmail.com wrote:
Hi Steven, I think this is a critical issue. Could you give priority to this fix?
On Fri, Jan 25, 2019 at 11:10:50PM +0800, Changbin Du wrote:
The userspace can ask kprobe to intercept strings at any memory address, including invalid kernel address. In this case, fetch_store_strlen() would crash since it uses general usercopy function.
For example, we can crash the kernel by doing something as below:
$ sudo kprobe 'p:do_sys_open +0(+0(%si)):string'
Note, I'm not able to reproduce this.
I just get:
sendmail-1085 [001] .... 277.344573: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879011: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879056: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879079: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879132: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879683: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.881521: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.881541: open: (do_sys_open+0x0/0x210) arg1="" <...>-1597 [005] .... 280.907662: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907694: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907772: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907825: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907891: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907947: open: (do_sys_open+0x0/0x210) arg1=(fault)
[ 103.620391] BUG: GPF in non-whitelisted uaccess (non-canonical address?) [ 103.622104] general protection fault: 0000 [#1] SMP PTI [ 103.623424] CPU: 10 PID: 1046 Comm: cat Not tainted 5.0.0-rc3-00130-gd73aba1-dirty #96 [ 103.625321] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-2-g628b2e6-dirty-20190104_103505-linux 04/01/2014 [ 103.628284] RIP: 0010:process_fetch_insn+0x1ab/0x4b0
What line number is the RIP on?
-- Steve
[ 103.629518] Code: 10 83 80 28 2e 00 00 01 31 d2 31 ff 48 8b 74 24 28 eb 0c 81 fa ff 0f 00 00 7f 1c 85 c0 75 18 66 66 90 0f ae e8 48 63 ca 89 f8 <8a> 0c 31 66 66 90 83 c2 01 84 c9 75 dc 89 54 24 34 89 44 24 28 48 [ 103.634032] RSP: 0018:ffff88845eb37ce0 EFLAGS: 00010246 [ 103.635312] RAX: 0000000000000000 RBX: ffff888456c4e5a8 RCX: 0000000000000000 [ 103.637057] RDX: 0000000000000000 RSI: 2e646c2f6374652f RDI: 0000000000000000 [ 103.638795] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 [ 103.640556] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 103.642297] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 103.644040] FS: 0000000000000000(0000) GS:ffff88846f000000(0000) knlGS:0000000000000000 [ 103.646019] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 103.647436] CR2: 00007ffc79758038 CR3: 0000000463360006 CR4: 0000000000020ee0 [ 103.649147] Call Trace: [ 103.649781] ? sched_clock_cpu+0xc/0xa0 [ 103.650747] ? do_sys_open+0x5/0x220 [ 103.651635] kprobe_trace_func+0x303/0x380 [ 103.652645] ? do_sys_open+0x5/0x220 [ 103.653528] kprobe_dispatcher+0x45/0x50 [ 103.654682] ? do_sys_open+0x1/0x220 [ 103.655875] kprobe_ftrace_handler+0x90/0xf0 [ 103.657282] ftrace_ops_assist_func+0x54/0xf0 [ 103.658564] ? __call_rcu+0x1dc/0x280 [ 103.659482] 0xffffffffc00000bf [ 103.660384] ? __ia32_sys_open+0x20/0x20 [ 103.661682] ? do_sys_open+0x1/0x220 [ 103.662863] do_sys_open+0x5/0x220 [ 103.663988] do_syscall_64+0x60/0x210 [ 103.665201] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 103.666862] RIP: 0033:0x7fc22fadccdd [ 103.668034] Code: 48 89 54 24 e0 41 83 e2 40 75 32 89 f0 25 00 00 41 00 3d 00 00 41 00 74 24 89 f2 b8 01 01 00 00 48 89 fe bf 9c ff ff ff 0f 05 <48> 3d 00 f0 ff ff 77 33 f3 c3 66 0f 1f 84 00 00 00 00 00 48 8d 44 [ 103.674029] RSP: 002b:00007ffc7972c3a8 EFLAGS: 00000287 ORIG_RAX: 0000000000000101 [ 103.676512] RAX: ffffffffffffffda RBX: 0000562f86147a21 RCX: 00007fc22fadccdd [ 103.678853] RDX: 0000000000080000 RSI: 00007fc22fae1428 RDI: 00000000ffffff9c [ 103.681151] RBP: ffffffffffffffff R08: 0000000000000000 R09: 0000000000000000 [ 103.683489] R10: 0000000000000000 R11: 0000000000000287 R12: 00007fc22fce90a8 [ 103.685774] R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000000 [ 103.688056] Modules linked in: [ 103.689131] ---[ end trace 43792035c28984a1 ]---
This can be fixed by using probe_mem_read() instead.
Signed-off-by: Changbin Du changbin.du@gmail.com Cc: stable@vger.kernel.org
kernel/trace/trace_kprobe.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index d5fb09ebba8b..9eaf07f99212 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -861,22 +861,14 @@ static const struct file_operations kprobe_profile_ops = { static nokprobe_inline int fetch_store_strlen(unsigned long addr) {
- mm_segment_t old_fs; int ret, len = 0; u8 c;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- pagefault_disable();
- do {
ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
len++; } while (c && ret == 0 && len < MAX_STRING_SIZE);ret = probe_mem_read(&c, (u8 *)addr + len, 1);
- pagefault_enable();
- set_fs(old_fs);
- return (ret < 0) ? ret : len;
} -- 2.19.1
On Wed, Feb 13, 2019 at 10:41:43AM -0500, Steven Rostedt wrote:
On Wed, 13 Feb 2019 22:36:40 +0800 Changbin Du changbin.du@gmail.com wrote:
Hi Steven, I think this is a critical issue. Could you give priority to this fix?
On Fri, Jan 25, 2019 at 11:10:50PM +0800, Changbin Du wrote:
The userspace can ask kprobe to intercept strings at any memory address, including invalid kernel address. In this case, fetch_store_strlen() would crash since it uses general usercopy function.
For example, we can crash the kernel by doing something as below:
$ sudo kprobe 'p:do_sys_open +0(+0(%si)):string'
Note, I'm not able to reproduce this.
I just get:
sendmail-1085 [001] .... 277.344573: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879011: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879056: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879079: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879132: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879683: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.881521: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.881541: open: (do_sys_open+0x0/0x210) arg1="" <...>-1597 [005] .... 280.907662: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907694: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907772: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907825: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907891: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907947: open: (do_sys_open+0x0/0x210) arg1=(fault)
[ 103.620391] BUG: GPF in non-whitelisted uaccess (non-canonical address?) [ 103.622104] general protection fault: 0000 [#1] SMP PTI [ 103.623424] CPU: 10 PID: 1046 Comm: cat Not tainted 5.0.0-rc3-00130-gd73aba1-dirty #96 [ 103.625321] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-2-g628b2e6-dirty-20190104_103505-linux 04/01/2014 [ 103.628284] RIP: 0010:process_fetch_insn+0x1ab/0x4b0
What line number is the RIP on?
I still can reproduce this bug on mainline (1f947a7a011fcceb14cb912f5481a53b18f1879a). But it seems your linux has already fix this issue.
Panic msg: i440FX-PIIX login: [ 265.640531] BUG: GPF in non-whitelisted uaccess (non-canonical address?) [ 265.644365] general protection fault: 0000 [#1] SMP PTI [ 265.645227] CPU: 0 PID: 2044 Comm: cat Not tainted 5.0.0-rc6+ #25 [ 265.646251] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-4-g29ba89e 04/01/2014 [ 265.647754] RIP: 0010:process_fetch_insn+0x1a3/0x450 [ 265.648498] Code: ff f0 80 48 03 80 83 80 88 21 00 00 01 31 c9 eb 10 48 83 c2 01 85 c0 75 1f 81 f9 ff 0f 00 00 7f 17 0f 01 cb 0f ae e8 44 89 e0 <40> 8a 32 0f 01 ca 83 c1 01 40 84 f6 75 d9 65 48 8b 14 25 40 5c 01 [ 265.651117] RSP: 0018:ffffc90001b1fd00 EFLAGS: 00050246 [ 265.651862] RAX: 0000000000000000 RBX: ffff88812d4a9100 RCX: 0000000000000000 [ 265.652917] RDX: 2e646c2f6374652f RSI: 00007ff31f818430 RDI: 00007ffffffff000 [ 265.653918] RBP: 0000000000000000 R08: 2e646c2f6374652f R09: 0000000000000000 [ 265.654881] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 [ 265.655815] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 265.656746] FS: 0000000000000000(0000) GS:ffff88807d600000(0000) knlGS:0000000000000000 [ 265.657838] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 265.658680] CR2: 00007fff979b8038 CR3: 000000002e7b0005 CR4: 00000000003606f0 [ 265.659748] Call Trace: [ 265.660225] kprobe_trace_func+0x278/0x360 [ 265.661119] ? trace_hardirqs_on+0x2c/0xd0 [ 265.661824] ? kmem_cache_free+0x1a7/0x1d0 [ 265.662366] ? do_sys_open+0x5/0x220 [ 265.662858] kprobe_dispatcher+0x36/0x50 [ 265.663362] ? do_sys_open+0x1/0x220 [ 265.663832] kprobe_ftrace_handler+0x92/0xf0 [ 265.664376] ftrace_ops_assist_func+0x81/0xf0 [ 265.664957] ? __call_rcu.constprop.49+0xca/0x210 [ 265.665583] 0xffffffffc00040bf [ 265.665990] ? __ia32_sys_open+0x20/0x20 [ 265.666502] ? do_sys_open+0x1/0x220 [ 265.667041] do_sys_open+0x5/0x220 [ 265.667483] do_syscall_64+0x60/0xf0 [ 265.667971] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 265.668613] RIP: 0033:0x7ff31f813cdd [ 265.669088] Code: 48 89 54 24 e0 41 83 e2 40 75 32 89 f0 25 00 00 41 00 3d 00 00 41 00 74 24 89 f2 b8 01 01 00 00 48 89 fe bf 9c ff ff ff 0f 05 <48> 3d 00 f0 ff ff 77 33 f3 c3 66 0f 1f 84 00 00 00 00 00 48 8d 44 [ 265.671330] RSP: 002b:00007fff978d8448 EFLAGS: 00000287 ORIG_RAX: 0000000000000101 [ 265.672206] RAX: ffffffffffffffda RBX: 000056396c8afa21 RCX: 00007ff31f813cdd [ 265.673065] RDX: 0000000000080000 RSI: 00007ff31f818428 RDI: 00000000ffffff9c [ 265.673887] RBP: ffffffffffffffff R08: 0000000000000000 R09: 0000000000000000 [ 265.674680] R10: 0000000000000000 R11: 0000000000000287 R12: 00007ff31fa200a8 [ 265.675465] R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000000 [ 265.676258] Modules linked in: [ 265.676972] ---[ end trace b0d3ddba0b051f18 ]---
The location is: changbin@laptop:/home/work/linux$ scripts/faddr2line --list vmlinux process_fetch_insn+0x1a3 process_fetch_insn+0x1a3/0x450:
raw_copy_from_user at arch/x86/include/asm/uaccess_64.h:75 70 if (!__builtin_constant_p(size)) 71 return copy_user_generic(dst, (__force void *)src, size); 72 switch (size) { 73 case 1: 74 __uaccess_begin_nospec();
75< __get_user_asm_nozero(*(u8 *)dst, (u8 __user *)src,
76 ret, "b", "b", "=q", 1); 77 __uaccess_end(); 78 return ret; 79 case 2: 80 __uaccess_begin_nospec();
(inlined by) __copy_from_user_inatomic at include/linux/uaccess.h:63 58 static __always_inline unsigned long 59 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) 60 { 61 kasan_check_write(to, n); 62 check_object_size(to, n, false);
63< return raw_copy_from_user(to, from, n);
64 } 65 66 static __always_inline unsigned long 67 __copy_from_user(void *to, const void __user *from, unsigned long n) 68 {
(inlined by) fetch_store_strlen at kernel/trace/trace_kprobe.c:873 868 old_fs = get_fs(); 869 set_fs(KERNEL_DS); 870 pagefault_disable(); 871 872 do {
873< ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
874 len++; 875 } while (c && ret == 0 && len < MAX_STRING_SIZE); 876 877 pagefault_enable(); 878 set_fs(old_fs);
(inlined by) process_fetch_insn_bottom at kernel/trace/trace_probe_tmpl.h:91 86 s3 = code; 87 stage3: 88 /* 3rd stage: store value to buffer */ 89 if (unlikely(!dest)) { 90 if (code->op == FETCH_OP_ST_STRING) {
91< ret += fetch_store_strlen(val + code->offset);
92 code++; 93 goto array; 94 } else 95 return -EILSEQ; 96 }
(inlined by) process_fetch_insn at kernel/trace/trace_kprobe.c:954 949 default: 950 return -EILSEQ; 951 } 952 code++; 953
954< return process_fetch_insn_bottom(code, val, dest, base);
955 } 956 NOKPROBE_SYMBOL(process_fetch_insn) 957 958 /* Kprobe handler */ 959 static nokprobe_inline void
process_fetch_insn+0x1a3/0x410:
adjust_stack_addr at kernel/trace/trace_uprobe.c:116 111 return addr - (n * sizeof(long)); 112 } 113 #else 114 static unsigned long adjust_stack_addr(unsigned long addr, unsigned int n) 115 {
116< return addr + (n * sizeof(long));
117 } 118 #endif 119 120 static unsigned long get_user_stack_nth(struct pt_regs *regs, unsigned int n) 121 {
(inlined by) get_user_stack_nth at kernel/trace/trace_uprobe.c:125 120 static unsigned long get_user_stack_nth(struct pt_regs *regs, unsigned int n) 121 { 122 unsigned long ret; 123 unsigned long addr = user_stack_pointer(regs); 124
125< addr = adjust_stack_addr(addr, n);
126 127 if (copy_from_user(&ret, (void __force __user *) addr, sizeof(ret))) 128 return 0; 129 130 return ret;
(inlined by) process_fetch_insn at kernel/trace/trace_uprobe.c:212 207 switch (code->op) { 208 case FETCH_OP_REG: 209 val = regs_get_register(regs, code->param); 210 break; 211 case FETCH_OP_STACK:
212< val = get_user_stack_nth(regs, code->param);
213 break; 214 case FETCH_OP_STACKP: 215 val = user_stack_pointer(regs); 216 break; 217 case FETCH_OP_RETVAL:
-- Steve
On Thu, 14 Feb 2019 08:05:24 +0800 Changbin Du changbin.du@gmail.com wrote:
On Wed, Feb 13, 2019 at 10:41:43AM -0500, Steven Rostedt wrote:
On Wed, 13 Feb 2019 22:36:40 +0800 Changbin Du changbin.du@gmail.com wrote:
Hi Steven, I think this is a critical issue. Could you give priority to this fix?
On Fri, Jan 25, 2019 at 11:10:50PM +0800, Changbin Du wrote:
The userspace can ask kprobe to intercept strings at any memory address, including invalid kernel address. In this case, fetch_store_strlen() would crash since it uses general usercopy function.
For example, we can crash the kernel by doing something as below:
$ sudo kprobe 'p:do_sys_open +0(+0(%si)):string'
Note, I'm not able to reproduce this.
I just get:
sendmail-1085 [001] .... 277.344573: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879011: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879056: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879079: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879132: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879683: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.881521: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.881541: open: (do_sys_open+0x0/0x210) arg1="" <...>-1597 [005] .... 280.907662: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907694: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907772: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907825: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907891: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907947: open: (do_sys_open+0x0/0x210) arg1=(fault)
[ 103.620391] BUG: GPF in non-whitelisted uaccess (non-canonical address?) [ 103.622104] general protection fault: 0000 [#1] SMP PTI [ 103.623424] CPU: 10 PID: 1046 Comm: cat Not tainted 5.0.0-rc3-00130-gd73aba1-dirty #96 [ 103.625321] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-2-g628b2e6-dirty-20190104_103505-linux 04/01/2014 [ 103.628284] RIP: 0010:process_fetch_insn+0x1ab/0x4b0
What line number is the RIP on?
I still can reproduce this bug on mainline (1f947a7a011fcceb14cb912f5481a53b18f1879a). But it seems your linux has already fix this issue.
No I didn't have the fix. I was running an older kernel actually. One before commit 9da3f2b74054406f87dff7101a569217ffceb29b was added. There's nothing actually wrong with that code, since kprobes is allowed to poke at anything. But that commit considers the kernel using copy from user to poke kernel address space is a security bug.
So yeah, I agree your patch should be added with a stable tag, with a Fixes: with that commit, since that commit is what causes it to bug.
I'll apply it and start testing it.
-- Steve
On Thu, Feb 14, 2019 at 08:04:18AM -0500, Steven Rostedt wrote:
On Thu, 14 Feb 2019 08:05:24 +0800 Changbin Du changbin.du@gmail.com wrote:
On Wed, Feb 13, 2019 at 10:41:43AM -0500, Steven Rostedt wrote:
On Wed, 13 Feb 2019 22:36:40 +0800 Changbin Du changbin.du@gmail.com wrote:
Hi Steven, I think this is a critical issue. Could you give priority to this fix?
On Fri, Jan 25, 2019 at 11:10:50PM +0800, Changbin Du wrote:
The userspace can ask kprobe to intercept strings at any memory address, including invalid kernel address. In this case, fetch_store_strlen() would crash since it uses general usercopy function.
For example, we can crash the kernel by doing something as below:
$ sudo kprobe 'p:do_sys_open +0(+0(%si)):string'
Note, I'm not able to reproduce this.
I just get:
sendmail-1085 [001] .... 277.344573: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879011: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879056: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879079: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879132: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.879683: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.881521: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1550 [003] .... 279.881541: open: (do_sys_open+0x0/0x210) arg1="" <...>-1597 [005] .... 280.907662: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907694: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907772: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907825: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907891: open: (do_sys_open+0x0/0x210) arg1=(fault) <...>-1597 [005] .... 280.907947: open: (do_sys_open+0x0/0x210) arg1=(fault)
[ 103.620391] BUG: GPF in non-whitelisted uaccess (non-canonical address?) [ 103.622104] general protection fault: 0000 [#1] SMP PTI [ 103.623424] CPU: 10 PID: 1046 Comm: cat Not tainted 5.0.0-rc3-00130-gd73aba1-dirty #96 [ 103.625321] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-2-g628b2e6-dirty-20190104_103505-linux 04/01/2014 [ 103.628284] RIP: 0010:process_fetch_insn+0x1ab/0x4b0
What line number is the RIP on?
I still can reproduce this bug on mainline (1f947a7a011fcceb14cb912f5481a53b18f1879a). But it seems your linux has already fix this issue.
No I didn't have the fix. I was running an older kernel actually. One before commit 9da3f2b74054406f87dff7101a569217ffceb29b was added. There's nothing actually wrong with that code, since kprobes is allowed to poke at anything. But that commit considers the kernel using copy from user to poke kernel address space is a security bug.
Glade to know that. And I wonder wether all such cases have been disclosed. I noticed the uprobe code also uses some usercopy functions.
So yeah, I agree your patch should be added with a stable tag, with a Fixes: with that commit, since that commit is what causes it to bug.
I'll apply it and start testing it.
-- Steve
On Thu, 14 Feb 2019 14:10:44 +0000 Changbin Du changbin.du@gmail.com wrote:
No I didn't have the fix. I was running an older kernel actually. One before commit 9da3f2b74054406f87dff7101a569217ffceb29b was added. There's nothing actually wrong with that code, since kprobes is allowed to poke at anything. But that commit considers the kernel using copy from user to poke kernel address space is a security bug.
Glade to know that. And I wonder wether all such cases have been disclosed. I noticed the uprobe code also uses some usercopy functions.
Well, uprobe shouldn't be poking at kernel addresses ;-)
-- Steve
linux-stable-mirror@lists.linaro.org