From e93970ecac526e9956717f5887776188b2682975 Mon Sep 17 00:00:00 2001 From: Christoph Paasch Date: Mon, 7 Aug 2017 23:59:08 -0700 Subject: [PATCH] mptcp/fullmesh: Fix null-pointer dereference to sk_socket One may encounter the following panic: [144721.501011] ================================================================== [144721.502551] Disabling lock debugging due to kernel taint [144721.504498] ================================================================== [144721.504528] BUG: unable to handle kernel NULL pointer dereference at (null) [144721.504534] IP: [] mptcp_init4_subsockets+0x76/0x5b0 [144721.504540] PGD 72dbe2067 PUD 72f6d2067 PMD 0 [144721.504546] Oops: 0000 [#1] SMP KASAN [144721.504607] Modules linked in: ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_nat xt_tcpudp xt_conntrack iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat iptable_filter ip_tables x_tables tun binfmt_misc ip_vs nf_conntrack libcrc32c crc32c_generic nfsd auth_rpcgss oid_registry nfs_acl nfs lockd grace fscache sunrpc intel_rapl iosf_mbi x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel sha256_ssse3 sch_fq sha256_generic hmac drbg ansi_cprng ast snd_pcm ttm drm_kms_helper aesni_intel snd_timer aes_x86_64 lrw gf128mul glue_helper ablk_helper snd cryptd drm soundcore pcspkr mptcp_olia cdc_ether mptcp_balia usbnet iTCO_wdt mei_me iTCO_vendor_support joydev ipmi_watchdog evdev r8152 mii mei shpchp battery 8250_fintek video tpm_tis [144721.504623] tpm acpi_power_meter acpi_pad button processor ipmi_si ipmi_poweroff ipmi_devintf ipmi_msghandler autofs4 ext4 crc16 mbcache jbd2 raid1 md_mod sg sd_mod hid_generic usbhid crc32c_intel ahci libahci libata i2c_i801 xhci_pci xhci_hcd scsi_mod igb usbcore usb_common i2c_algo_bit dca ptp pps_core fan thermal i2c_hid hid [144721.504626] CPU: 4 PID: 2471 Comm: kworker/u16:2 Tainted: G B 4.4.70+ #2 [144721.504629] Hardware name: Supermicro Super Server/X11SSM-F, BIOS 1.0b 12/29/2015 [144721.504631] Workqueue: mptcp_wq create_subflow_worker [144721.504633] task: ffff880749498000 ti: ffff88070e350000 task.ti: ffff88070e350000 [144721.504637] RIP: 0010:[] [] mptcp_init4_subsockets+0x76/0x5b0 [144721.504638] RSP: 0018:ffff88070e357a18 EFLAGS: 00010246 [144721.504639] RAX: ffffed00e1c6af95 RBX: ffff88072ec98000 RCX: 000000000000004a [144721.504641] RDX: ffffed00e1c6af95 RSI: 0000000000000000 RDI: ffff88070e357a58 [144721.504642] RBP: 0000000000000000 R08: 0000000000000005 R09: ffffed00e1c6af94 [144721.504644] R10: ffff88070e357ca7 R11: ffffed00e1c6af95 R12: ffff88070e357d48 [144721.504645] R13: ffff88072ec98000 R14: ffff88070e357d40 R15: ffff880078e0f960 [144721.504647] FS: 0000000000000000(0000) GS:ffff880756300000(0000) knlGS:0000000000000000 [144721.504651] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [144721.504654] CR2: 0000000000000000 CR3: 0000000875804000 CR4: 00000000003406e0 [144721.504658] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [144721.504661] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [144721.504662] Stack: [144721.504672] ffff88070e357f58 ffff88070e357f58 ffffffffffff8000 ffff88072ec98248 [144721.504680] ffffffff81a03440 0000000000000000 ffffffff811526e1 ffffffff811947a4 [144721.504690] ffff88070e357f58 0000000000000000 ffffffffffff8000 ffffffff810ca43e [144721.504692] Call Trace: [144721.504697] [] ? __module_text_address+0x11/0xa0 [144721.504701] [] ? is_ftrace_trampoline+0x54/0x80 [144721.504705] [] ? __kernel_text_address+0x5e/0x80 [144721.504710] [] ? print_context_stack+0x55/0xf0 [144721.504714] [] ? dump_trace+0x110/0x2a0 [144721.504720] [] ? __list_add+0x71/0xf0 [144721.504725] [] ? deactivate_slab+0x13d/0x3e0 [144721.504729] [] ? save_stack_trace+0x3d/0x80 [144721.504732] [] ? create_subflow_worker+0x9f/0x7d0 [144721.504736] [] ? set_track+0x6e/0x120 [144721.504740] [] ? ___slab_alloc+0x138/0x440 [144721.504744] [] ? create_subflow_worker+0x9f/0x7d0 [144721.504750] [] ? autoremove_wake_function+0x3c/0x50 The reason is that we check for sock_orphan after the while-loop to create the additional subflows for the first pair. We have to move the checks a bit higher before attempting to create new subflows. Github-issue: https://github.com/multipath-tcp/mptcp/issues/191 Reported-by: https://github.com/jarmediagmbh Fixes: d0f3a6d158d5c (mptcp: fullmesh path manager extension (creation of multiple subflows per pair of IPs)) Signed-off-by: Christoph Paasch Signed-off-by: Matthieu Baerts (cherry picked from commit 5b19eb97047cc4a39e623c1014682e64ad80e72e) Signed-off-by: Matthieu Baerts --- net/mptcp/mptcp_fullmesh.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/mptcp/mptcp_fullmesh.c b/net/mptcp/mptcp_fullmesh.c index b1ac1a442a62ca..8ab87237e006d9 100644 --- a/net/mptcp/mptcp_fullmesh.c +++ b/net/mptcp/mptcp_fullmesh.c @@ -476,6 +476,13 @@ static void create_subflow_worker(struct work_struct *work) mutex_lock(&mpcb->mpcb_mutex); lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); + if (sock_flag(meta_sk, SOCK_DEAD)) + goto exit; + + if (mpcb->master_sk && + !tcp_sk(mpcb->master_sk)->mptcp->fully_established) + goto exit; + /* Create the additional subflows for the first pair */ if (fmp->first_pair == 0 && mpcb->master_sk) { struct mptcp_loc4 loc; @@ -496,13 +503,6 @@ static void create_subflow_worker(struct work_struct *work) } iter++; - if (sock_flag(meta_sk, SOCK_DEAD)) - goto exit; - - if (mpcb->master_sk && - !tcp_sk(mpcb->master_sk)->mptcp->fully_established) - goto exit; - mptcp_for_each_bit_set(fmp->rem4_bits, i) { struct fullmesh_rem4 *rem; u8 remaining_bits;