Skip to content

Instantly share code, notes, and snippets.

@agentzh
Created October 1, 2020 21:38
Show Gist options
  • Save agentzh/7c98fea4d7461f91e4f1a3b237f6fd77 to your computer and use it in GitHub Desktop.
Save agentzh/7c98fea4d7461f91e4f1a3b237f6fd77 to your computer and use it in GitHub Desktop.
commit db30ccf5b9987d7b9e8735aa038603f372190f8f
Author: Sultan Alsawaf <sultan@openresty.com>
Date: Wed Sep 30 21:09:26 2020 -0700
WORKINPROGRESS: stp_utrace: fix NULL pointer deref in get_utrace_lock()
task_utrace_struct() can return NULL via __task_utrace_struct(). This fixes
the following crash:
BUG: unable to handle kernel NULL pointer dereference at (null)
#9 [ffff8843e56ffd20] get_utrace_lock at ffffffffc08258c6 [orxray_c_fgraph_X_40544]
The reason why it can return NULL is because engine->ops is protected by
utrace->lock, but we don't have the utrace pointer, and the purpose of
get_utrace_lock() is to get the utrace pointer. Therefore, there's no way
to ensure engine->ops remains unchanged inside get_utrace_lock(), so
get_utrace_lock()'s checks on engine->ops can be incorrect/stale, which
leads to the NULL pointer dereference.
XXX: There is still a general protection fault implicated in this call
chain:
[ 2082.921207] general protection fault: 0000 [#1] SMP
[ 2082.921229] Modules linked in: orxray_lj_lua_fgraph_X_43478(OE) orxray_lgc_X_39811(OE) ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_addrtype br_netfilter ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ebtable_nat ebtable_broute bridge stp llc ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat iptable_mangle iptable_security iptable_raw nf_conntrack ip_set nfnetlink ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter overlay(T) ppdev crc32_pclmul ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper cryptd sg parport_pc joydev parport virtio_balloon pcspkr i2c_piix4 ip_tables xfs libcrc32c sr_mod cdrom sd_mod crc_t10dif crct10dif_generic
[ 2082.921396] ata_generic pata_acpi virtio_net virtio_console virtio_scsi cirrus drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm ata_piix virtio_pci drm libata crct10dif_pclmul virtio_ring crct10dif_common crc32c_intel serio_raw virtio floppy drm_panel_orientation_quirks dm_mirror dm_region_hash dm_log dm_mod [last unloaded: orxray_lj_lua_fgraph_X_30882]
[ 2082.921472] CPU: 19 PID: 45825 Comm: sleep Tainted: G OE ------------ T 3.10.0-1062.4.2.el7.x86_64 #1
[ 2082.921490] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014
[ 2082.921504] task: ffffa0cf6bf762a0 ti: ffffa0d097564000 task.ti: ffffa0d097564000
[ 2082.921516] RIP: 0010:[<ffffffffc0aad152>] [<ffffffffc0aad152>] __task_utrace_struct+0x65/0x8d [orxray_lj_lua_fgraph_X_43478]
[ 2082.921543] RSP: 0018:ffffa0d097567df8 EFLAGS: 00010286
[ 2082.921553] RAX: dead0000000000b8 RBX: 0000000000000078 RCX: 7cc1f0f1e17762a0
[ 2082.921565] RDX: 0000000000000000 RSI: ffffa0cf52d74620 RDI: ffffa0cf6bf762a0
[ 2082.921577] RBP: ffffa0d097567df8 R08: 0000000000000040 R09: 0000000180080002
[ 2082.921589] R10: 00000000d0e78001 R11: ffffa0d0d0e79000 R12: ffffa0cf52d74620
[ 2082.921599] R13: 0000000000000001 R14: ffffffffc0b4e7c0 R15: 0000000000000040
[ 2082.921614] FS: 0000000000000000(0000) GS:ffffa0d0f6ac0000(0000) knlGS:0000000000000000
[ 2082.921627] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2082.921637] CR2: 00007ffdb2bd48c9 CR3: 00000001f8778000 CR4: 0000000000340fe0
[ 2082.921650] Call Trace:
[ 2082.921659] [<ffffffffc0ab493e>] get_utrace_lock+0x2e/0xc2 [orxray_lj_lua_fgraph_X_43478]
[ 2082.921674] [<ffffffffc0ab4a98>] utrace_set_events+0x24/0x149 [orxray_lj_lua_fgraph_X_43478]
[ 2082.921690] [<ffffffffc0accc04>] __stp_utrace_task_finder_target_quiesce+0x76/0x2cb [orxray_lj_lua_fgraph_X_43478]
[ 2082.921708] [<ffffffffc0ab4f63>] start_callback+0x85/0xd6 [orxray_lj_lua_fgraph_X_43478]
[ 2082.921722] [<ffffffffc0ab7bcb>] utrace_report_syscall_exit+0xcb/0x127 [orxray_lj_lua_fgraph_X_43478]
[ 2082.921739] [<ffffffff9a23c22d>] syscall_trace_leave+0xfd/0x110
[ 2082.921752] [<ffffffff9a98d220>] int_check_syscall_exit_work+0x13/0x1c
[ 2082.921764] Code: 48 c1 e2 3d 48 01 d0 48 89 fa 48 c1 e2 3f 48 01 d0 48 c1 e8 3b 48 8b 04 c5 e0 2a ca c0 48 85 c0 74 2a 48 83 e8 48 48 85 c0 74 18 <48> 39 78 58 74 12 48 8b 40 48 48 85 c0 74 0b 48 83 e8 48 48 85
[ 2082.921833] RIP [<ffffffffc0aad152>] __task_utrace_struct+0x65/0x8d [orxray_lj_lua_fgraph_X_43478]
[ 2082.922181] RSP <ffffa0d097567df8>
[ 2082.924855] ---[ end trace 6a4bf25b82a57fe8 ]---
__task_utrace_struct+0x65 corresponds to `if (utrace->task == task)`.
Maybe utrace is invalid in this context? But I have no idea why that could
be.
diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c
index abdf7dacb..33f03b96f 100644
--- a/runtime/stp_utrace.c
+++ b/runtime/stp_utrace.c
@@ -1090,6 +1090,9 @@ static struct utrace *get_utrace_lock(struct task_struct *target,
}
utrace = task_utrace_struct(target);
+ if (unlikely(!utrace))
+ return ERR_PTR(-ESRCH);
+
spin_lock(&utrace->lock);
if (unlikely(utrace->reap) || unlikely(!engine->ops) ||
unlikely(engine->ops == &utrace_detached_ops)) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment