This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[Bug runtime/16718] New: kernel crash in _stp_copy_from_user()
- From: "dsmith at redhat dot com" <sourceware-bugzilla at sourceware dot org>
- To: systemtap at sourceware dot org
- Date: Mon, 17 Mar 2014 16:11:59 +0000
- Subject: [Bug runtime/16718] New: kernel crash in _stp_copy_from_user()
- Auto-submitted: auto-generated
https://sourceware.org/bugzilla/show_bug.cgi?id=16718
Bug ID: 16718
Summary: kernel crash in _stp_copy_from_user()
Product: systemtap
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: runtime
Assignee: systemtap at sourceware dot org
Reporter: dsmith at redhat dot com
I was doing some testing on bug #16716, passing a value of -1 as the 'addrlen'
argument to the bind syscall. This crashed the kernel:
====
[ 137.144041] BUG: unable to handle kernel paging request at
ffff88007a77e000
[ 137.144041] IP: [<ffffffff813d5ed2>] memset+0x42/0xb0
[ 137.144041] PGD 2dc8067 PUD 2dcb067 PMD 78eee063 PTE 800000007a77e161
[ 137.144041] Oops: 0003 [#1] SMP
[ 137.144041] Modules linked in:
stap_49e2cbecb8a3c3d38ae6787d3e13b19e__1151(OF) nfsv3 rpcsec_gss_krb5
nfsv4 dns_resolver nfs fscache ip6t_rpfilter ip6t_REJECT xt_conntrack
cfg80211 rfkill ebtable_nat ebtable_broute bridge stp llc ebtable_filter
ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6
ip6table_mangle ip6table_security ip6table_raw ip6table_filter
ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4
nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw ppdev
kvm_amd kvm snd_hda_codec_generic snd_hda_intel snd_hda_codec serio_raw
snd_hwdep virtio_balloon snd_seq virtio_console snd_seq_device
virtio_net snd_pcm parport_pc pvpanic parport snd_timer snd i2c_piix4
soundcore nfsd auth_rpcgss nfs_acl lockd sunrpc virtio_blk qxl
drm_kms_helper ttm drm virtio_pci virtio_ring virtio i2c_core
ata_generic pata_acpi
[ 137.144041] CPU: 1 PID: 1153 Comm: bind64 Tainted: GF O
3.14.0-0.rc5.git2.1.fc21.x86_64 #1
[ 137.144041] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[ 137.144041] task: ffff88007aed0000 ti: ffff88007ab80000 task.ti:
ffff88007ab80000
[ 137.144041] RIP: 0010:[<ffffffff813d5ed2>] [<ffffffff813d5ed2>]
memset+0x42/0xb0
[ 137.144041] RSP: 0018:ffff88007ab81db0 EFLAGS: 00010007
[ 137.144041] RAX: 0000000000000000 RBX: ffff88007a770000 RCX:
03fffffffffffc87
[ 137.144041] RDX: ffffffffffffffff RSI: 0000000000000000 RDI:
ffff88007a77dfe0
[ 137.144041] RBP: ffff88007ab81e10 R08: 00007fff27c52c10 R09:
0000000000000000
[ 137.144041] R10: ffff88007a770220 R11: 3531363135353930 R12:
ffff88007a770f18
[ 137.144041] R13: ffffffffffffffff R14: ffff88007a7704e8 R15:
ffff88007a771158
[ 137.144041] FS: 00007f751d008740(0000) GS:ffff88007d400000(0000)
knlGS:0000000000000000
[ 137.144041] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 137.144041] CR2: ffff88007a77e000 CR3: 0000000070f99000 CR4:
00000000000006e0
[ 137.144041] Stack:
[ 137.144041] ffffffffa058f760 0000000000000028 ffff88007ab81de0
0000000000000002
[ 137.144041] ffff88007a770220 00007ffffffff000 0000000000000001
ffff88007ab81ed0
[ 137.144041] 0000006b6eb55e04 ffffffffa0596ac0 ffffffff8166c251
ffff88007ab81ed0
[ 137.144041] Call Trace:
[ 137.144041] [<ffffffffa058f760>] ? probe_2159+0xa70/0xf30
[stap_49e2cbecb8a3c3d38ae6787d3e13b19e__1151]
[ 137.144041] [<ffffffff8166c251>] ? SyS_bind+0x1/0x10
[ 137.144041] [<ffffffffa0591b21>] enter_kprobe_probe+0x161/0x310
[stap_49e2cbecb8a3c3d38ae6787d3e13b19e__1151]
[ 137.144041] [<ffffffff8166c251>] ? SyS_bind+0x1/0x10
[ 137.144041] [<ffffffff817df2fc>] kprobe_ftrace_handler+0xec/0x130
[ 137.144041] [<ffffffff8166c250>] ? SyS_socketpair+0x260/0x260
[ 137.144041] [<ffffffff817e5929>] ? system_call_fastpath+0x16/0x1b
[ 137.144041] [<ffffffff8116c746>] ftrace_ops_list_func+0x126/0x140
[ 137.144041] [<ffffffff817e56c2>] ftrace_regs_call+0x5/0x77
[ 137.144041] [<ffffffff8115472c>] ? __audit_syscall_entry+0x9c/0xf0
[ 137.144041] [<ffffffff8166c250>] ? SyS_socketpair+0x260/0x260
[ 137.144041] [<ffffffff8166c255>] ? SyS_bind+0x5/0x10
[ 137.144041] [<ffffffff817e5929>] ? system_call_fastpath+0x16/0x1b
[ 137.144041] Code: f9 41 83 e1 07 75 70 48 89 d1 48 c1 e9 06 74 39 66
0f 1f 84 00 00 00 00 00 48 ff c9 48 89 07 48 89 47 08 48 89 47 10 48 89
47 18 <48> 89 47 20 48 89 47 28 48 89 47 30 48 89 47 38 48 8d 7f 40 75
[ 137.144041] RIP [<ffffffff813d5ed2>] memset+0x42/0xb0
[ 137.144041] RSP <ffff88007ab81db0>
[ 137.144041] CR2: ffff88007a77e000
[ 137.144041] ---[ end trace 5b5823bf3ac17712 ]---
[ 137.144041] BUG: sleeping function called from invalid context at
kernel/locking/rwsem.c:20
[ 137.144041] in_atomic(): 1, irqs_disabled(): 1, pid: 1153, name: bind64
[ 137.144041] INFO: lockdep is turned off.
[ 137.144041] irq event stamp: 3286
[ 137.144041] hardirqs last enabled at (3285): [<ffffffff8111bc59>]
current_kernel_time+0x69/0xd0
[ 137.144041] hardirqs last disabled at (3286): [<ffffffff817df23e>]
kprobe_ftrace_handler+0x2e/0x130
[ 137.144041] softirqs last enabled at (3278): [<ffffffff81365620>]
sel_netnode_sid+0x2f0/0x380
[ 137.144041] softirqs last disabled at (3276): [<ffffffff813654a2>]
sel_netnode_sid+0x172/0x380
[ 137.144041] CPU: 1 PID: 1153 Comm: bind64 Tainted: GF D O
3.14.0-0.rc5.git2.1.fc21.x86_64 #1
[ 137.144041] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[ 137.144041] 0000000000000000 00000000bcd95af8 ffff88007ab819f8
ffffffff817d1ad2
[ 137.144041] 0000000000000000 ffff88007ab81a20 ffffffff810d0165
ffff8800759f8478
[ 137.144041] ffff8800759f84d8 ffff88007aed0000 ffff88007ab81a48
ffffffff817d995a
[ 137.144041] Call Trace:
[ 137.144041] [<ffffffff817d1ad2>] dump_stack+0x4d/0x66
[ 137.144041] [<ffffffff810d0165>] __might_sleep+0x175/0x230
[ 137.144041] [<ffffffff817d995a>] down_read+0x2a/0xa0
[ 137.144041] [<ffffffff810aeb23>] exit_signals+0x33/0x150
[ 137.144041] [<ffffffff810995c2>] do_exit+0xd2/0xd00
[ 137.144041] [<ffffffff8110cff8>] ? kmsg_dump+0x1c8/0x250
[ 137.144041] [<ffffffff8110ce64>] ? kmsg_dump+0x34/0x250
[ 137.144041] [<ffffffff817dca3c>] oops_end+0x9c/0xe0
[ 137.144041] [<ffffffff817cbb32>] no_context+0x292/0x2b5
[ 137.144041] [<ffffffff817cbbd3>] __bad_area_nosemaphore+0x7e/0x1d5
[ 137.144041] [<ffffffff817cbd3d>] bad_area_nosemaphore+0x13/0x15
[ 137.144041] [<ffffffff817df811>] __do_page_fault+0xc1/0x600
[ 137.144041] [<ffffffff81199821>] ? irq_work_queue+0x71/0xc0
[ 137.144041] [<ffffffff8110b44c>] ? wake_up_klogd+0x3c/0x50
[ 137.144041] [<ffffffff817dfd5e>] do_page_fault+0xe/0x10
[ 137.144041] [<ffffffff817df388>] do_async_page_fault+0x28/0xa0
[ 137.144041] [<ffffffff817dbde8>] async_page_fault+0x28/0x30
[ 137.144041] [<ffffffff813d5ed2>] ? memset+0x42/0xb0
[ 137.144041] [<ffffffffa058f760>] ? probe_2159+0xa70/0xf30
[stap_49e2cbecb8a3c3d38ae6787d3e13b19e__1151]
[ 137.144041] [<ffffffff8166c251>] ? SyS_bind+0x1/0x10
[ 137.144041] [<ffffffffa0591b21>] enter_kprobe_probe+0x161/0x310
[stap_49e2cbecb8a3c3d38ae6787d3e13b19e__1151]
[ 137.144041] [<ffffffff8166c251>] ? SyS_bind+0x1/0x10
[ 137.144041] [<ffffffff817df2fc>] kprobe_ftrace_handler+0xec/0x130
[ 137.144041] [<ffffffff8166c250>] ? SyS_socketpair+0x260/0x260
[ 137.144041] [<ffffffff817e5929>] ? system_call_fastpath+0x16/0x1b
[ 137.144041] [<ffffffff8116c746>] ftrace_ops_list_func+0x126/0x140
[ 137.144041] [<ffffffff817e56c2>] ftrace_regs_call+0x5/0x77
[ 137.144041] [<ffffffff8115472c>] ? __audit_syscall_entry+0x9c/0xf0
[ 137.144041] [<ffffffff8166c250>] ? SyS_socketpair+0x260/0x260
[ 137.144041] [<ffffffff8166c255>] ? SyS_bind+0x5/0x10
[ 137.144041] [<ffffffff817e5929>] ? system_call_fastpath+0x16/0x1b
[ 137.144041] note: bind64[1153] exited with preempt_count 3
[ 138.281104] stap_49e2cbecb8a3c3d38ae6787d3e13b19e__1151 context[1]
stuck: kernel.function("SyS_bind@net/socket.c:1519").call
====
I tracked this down to a problem in _stp_copy_from_user(). The syscall.bind
probe alias ends up calling _struct_sockaddr_u_impl(). In this case, 'len' was
-1:
====
function _struct_sockaddr_u_impl:string(uaddr:long, len:long, what:long)
%{ /* pure */
//...
size_t len = STAP_ARG_len < 128 ? STAP_ARG_len: 128;
// ...
if (_stp_copy_from_user(CONTEXT->buf, ptr, len))
//...
}
If STAP_ARG_len is -1, len is -1 (since -1 is less than 128), which gets
passed to _stp_copy_from_user(). _stp_copy_from_user() takes an unsigned
value. I'm surprised the compiler didn't complain about signed vs.
unsigned here.
Notice how the last thing before async_page_fault() is memset() in the kernel
backtrace? I thought that was odd until I looked back at _stp_copy_from_user()
and saw this:
===
if (access_ok(VERIFY_READ, src, count))
count = __copy_from_user_inatomic(dst, src, count);
else
memset(dst, 0, count);
===
In this call, _stp_copy_from_user() got 18446744073709551615 as the length to
copy. The access_ok() call failed (correctly), since that many bytes couldn't
be accessed. So, then we try to zero out that many bytes. Since 'dst' wasn't
that large, we crashed the kernel.
I think the fix here is to make _stp_copy_from_user() just return -EFAULT if
access_ok() fails and let the caller handle things. Looking at all the calls to
_stp_copy_from_user(), all but one call doesn't expect the destination to be
cleared out on failure.
--
You are receiving this mail because:
You are the assignee for the bug.