Message ID | 20230202090509.2774062-1-iam@sung-woo.kim |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2388:b0:96:219d:e725 with SMTP id i8csp179264dyf; Thu, 2 Feb 2023 01:15:32 -0800 (PST) X-Google-Smtp-Source: AK7set/EYn/lpszMmF/4VnzZRulU5doy0oNO9HmS/+4PBpVItloHLpkkc9QbI6FbMf8Wjml2we7F X-Received: by 2002:a17:90b:e0b:b0:230:3af9:16f with SMTP id ge11-20020a17090b0e0b00b002303af9016fmr1402462pjb.0.1675329332545; Thu, 02 Feb 2023 01:15:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675329332; cv=none; d=google.com; s=arc-20160816; b=0Zj57WA1Snc+Qrh4MhQVsKNIhDc/WpP/+lbrfm19x2ojQ8ncS+SANhe6PFALVWeL3+ nEyQ4Q0vlX79ucFp1jNy4j/DUzeJFKFsamHojqib9HEoru7Fm7bYvH53KseoNsNr6FBZ NGP57I35GQcETU3y2vBDdZFJy502XJLGxF9W4RCLHlXk9zqntE/DXI00p7xQd0mXZC+R /8wEvNpLduJ1EVw8zRl/x3hE3uVygpMWZK7ydRkEuegjkugbjXofjSze8tyZiywip7QS 16dr1b/DMwONQPRA0CRhxe9aGDy9DZa3cHdGLhmIUDLgm+BvgDUL8WoOGX84ewXMGMmF JQBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=zIRdF85vz4XW6DcLekDt+urDLZMgRkhDxffDT09XGig=; b=vvE9Ir4rDA+f+h4S4Bk8H18bphkaVjqumcdUJv3Ten2js2kXk6qdMLR+TXeO9/AKpR GXpSk+wcmzLnuJBv2fPZtEb4dAQne4ujqF6dj/3zya7d907BYH7+IGHSU1408GLPzI2K zvlP+00INeLnJXUypb8VJzwWlS1VQ5EKAR/PB0FDxDOrdMIA4w5+B3HVCJRsLRMDUE/i c9ro4POaj04G5RDjT71xd63cTQNo1vPlWVrZWp8XpYrlTB7KDbPZ+j2y5oCaNy6wwM0b mnJj/8thGDxoG+5BwNL/TbKSvW/PYC49TnRDHvzarvVf75qh241ciIC3IpH8cS+BCAcD XTig== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t69-20020a638148000000b004e5460b2e34si14667624pgd.234.2023.02.02.01.15.20; Thu, 02 Feb 2023 01:15:32 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232386AbjBBJH6 (ORCPT <rfc822;il.mystafa@gmail.com> + 99 others); Thu, 2 Feb 2023 04:07:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229602AbjBBJH5 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 2 Feb 2023 04:07:57 -0500 Received: from mail-il1-f169.google.com (mail-il1-f169.google.com [209.85.166.169]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D19DC5457E; Thu, 2 Feb 2023 01:07:54 -0800 (PST) Received: by mail-il1-f169.google.com with SMTP id k12so511989ilv.10; Thu, 02 Feb 2023 01:07:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zIRdF85vz4XW6DcLekDt+urDLZMgRkhDxffDT09XGig=; b=v3/AjWBkPGYl8kZF6pnz+36Rs5AN0jHmUCERNFHTjZL+/aGN640pU7HIdm3j734V6i Miy1Tcc3w9MfVzJyV8/iEFWWOO3xGh8EzbALzUYhUhD8VwjAKDMpjNO7O6G52etYmiFn XWuqWZT7/M7y9XWEOHnL5f85f6aOxY7gS5x/L9ypzzBGKMlxH6TTZnIew14Vvdy+PvBs yvkq0SWRG8WidfW1jUh4BSbNmZ4u8CfNNtTTeMPwqaiAURiLEJTzA0qONRvJ5FAer6Mk SKzmpouLyjDAih6P8z3qEctda0plgayGq96lZOtyDWwqsfXqovXFOggjPaCsUGRsEWuQ 5M9w== X-Gm-Message-State: AO0yUKXbzENfXT0UsCFweJ1wnERo9ablNIXCQ83wIvQ2WH5q2P105Q/N +p1KJDq17S7c0R9yalFC0X8= X-Received: by 2002:a92:c56a:0:b0:310:eb55:3856 with SMTP id b10-20020a92c56a000000b00310eb553856mr1376591ilj.9.1675328873930; Thu, 02 Feb 2023 01:07:53 -0800 (PST) Received: from noodle.cs.purdue.edu (switch-lwsn2133-z1r11.cs.purdue.edu. [128.10.127.250]) by smtp.googlemail.com with ESMTPSA id x12-20020a92dc4c000000b003110c59e2easm2060637ilq.37.2023.02.02.01.07.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Feb 2023 01:07:53 -0800 (PST) From: Sungwoo Kim <iam@sung-woo.kim> To: happiness.sung.woo@gmail.com Cc: benquike@gmail.com, davem@davemloft.net, daveti@purdue.edu, edumazet@google.com, johan.hedberg@gmail.com, kuba@kernel.org, linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, luiz.dentz@gmail.com, marcel@holtmann.org, netdev@vger.kernel.org, pabeni@redhat.com, wuruoyu@me.com, Sungwoo Kim <iam@sung-woo.kim> Subject: [PATCH] Bluetooth: L2CAP: Fix use-after-free Date: Thu, 2 Feb 2023 04:05:10 -0500 Message-Id: <20230202090509.2774062-1-iam@sung-woo.kim> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230123091708.4112735-1-git@sung-woo.kim> References: <20230123091708.4112735-1-git@sung-woo.kim> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756710129904282596?= X-GMAIL-MSGID: =?utf-8?q?1756710129904282596?= |
Series |
Bluetooth: L2CAP: Fix use-after-free
|
|
Commit Message
Sungwoo Kim
Feb. 2, 2023, 9:05 a.m. UTC
Due to the race condition between l2cap_sock_cleanup_listen and
l2cap_sock_close_cb, l2cap_sock_kill can receive already freed sk,
resulting in use-after-free inside l2cap_sock_kill.
This patch prevent this by adding a null check in l2cap_sock_kill.
Context 1:
l2cap_sock_cleanup_listen();
// context switched
l2cap_chan_lock(chan);
l2cap_sock_kill(sk); // <-- sk is already freed below
Context 2:
l2cap_chan_timeout();
l2cap_chan_lock(chan);
chan->ops->close(chan);
l2cap_sock_close_cb()
l2cap_sock_kill(sk); // <-- sk is freed here
l2cap_chan_unlock(chan);
Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
---
net/bluetooth/l2cap_sock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Comments
On Thu, Feb 2, 2023 at 10:07 AM Sungwoo Kim <iam@sung-woo.kim> wrote: > > Due to the race condition between l2cap_sock_cleanup_listen and > l2cap_sock_close_cb, l2cap_sock_kill can receive already freed sk, > resulting in use-after-free inside l2cap_sock_kill. > This patch prevent this by adding a null check in l2cap_sock_kill. > > Context 1: > l2cap_sock_cleanup_listen(); > // context switched > l2cap_chan_lock(chan); > l2cap_sock_kill(sk); // <-- sk is already freed below But sk is used in l2cap_sock_cleanup_listen() and should not be NULL... while ((sk = bt_accept_dequeue(parent, NULL))) { ... l2cap_sock_kill(sk); .. } It would help if you send us a stack trace ... > > Context 2: > l2cap_chan_timeout(); > l2cap_chan_lock(chan); > chan->ops->close(chan); > l2cap_sock_close_cb() > l2cap_sock_kill(sk); // <-- sk is freed here > l2cap_chan_unlock(chan); > Please add a Fixes: tag > Signed-off-by: Sungwoo Kim <iam@sung-woo.kim> > --- > net/bluetooth/l2cap_sock.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c > index ca8f07f35..657704059 100644 > --- a/net/bluetooth/l2cap_sock.c > +++ b/net/bluetooth/l2cap_sock.c > @@ -1245,7 +1245,7 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, > */ > static void l2cap_sock_kill(struct sock *sk) > { > - if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) > + if (!sk || !sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) > return; > > BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state)); > -- > 2.25.1 >
On Thu, Feb 2, 2023 at 4:26 AM Eric Dumazet <edumazet@google.com> wrote: > > On Thu, Feb 2, 2023 at 10:07 AM Sungwoo Kim <iam@sung-woo.kim> wrote: > > > > Due to the race condition between l2cap_sock_cleanup_listen and > > l2cap_sock_close_cb, l2cap_sock_kill can receive already freed sk, > > resulting in use-after-free inside l2cap_sock_kill. > > This patch prevent this by adding a null check in l2cap_sock_kill. > > > > Context 1: > > l2cap_sock_cleanup_listen(); > > // context switched > > l2cap_chan_lock(chan); > > l2cap_sock_kill(sk); // <-- sk is already freed below > > But sk is used in l2cap_sock_cleanup_listen() > and should not be NULL... > > while ((sk = bt_accept_dequeue(parent, NULL))) { > ... > l2cap_sock_kill(sk); > .. > } > > It would help if you send us a stack trace ... Here is the stack trace and l2cap_sock.c: https://gist.github.com/swkim101/5c3b8cb7c7d7172aef23810c9412f323 ================================================================== BUG: KASAN: use-after-free in l2cap_sock_kill (/v6.1-rc2/./include/net/sock.h:986 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1281) Read of size 8 at addr ffff88800f7f4060 by task l2cap-server/1764 CPU: 0 PID: 1764 Comm: l2cap-server Not tainted 6.1.0-rc2 #129 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 Call Trace: <TASK> dump_stack_lvl (/v6.1-rc2/lib/dump_stack.c:105) print_address_description+0x7e/0x360 print_report (/v6.1-rc2/mm/kasan/report.c:187 /v6.1-rc2/mm/kasan/report.c:389) ? __virt_addr_valid (/v6.1-rc2/./include/linux/mmzone.h:1855 /v6.1-rc2/arch/x86/mm/physaddr.c:65) ? kasan_complete_mode_report_info (/v6.1-rc2/mm/kasan/report_generic.c:104 /v6.1-rc2/mm/kasan/report_generic.c:127 /v6.1-rc2/mm/kasan/report_generic.c:136) ? l2cap_sock_kill (/v6.1-rc2/./include/net/sock.h:986 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1281) kasan_report (/v6.1-rc2/mm/kasan/report.c:? /v6.1-rc2/mm/kasan/report.c:484) ? l2cap_sock_kill (/v6.1-rc2/./include/net/sock.h:986 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1281) kasan_check_range (/v6.1-rc2/mm/kasan/generic.c:85 /v6.1-rc2/mm/kasan/generic.c:115 /v6.1-rc2/mm/kasan/generic.c:128 /v6.1-rc2/mm/kasan/generic.c:159 /v6.1-rc2/mm/kasan/generic.c:180 /v6.1-rc2/mm/kasan/generic.c:189) __kasan_check_read (/v6.1-rc2/mm/kasan/shadow.c:31) l2cap_sock_kill (/v6.1-rc2/./include/net/sock.h:986 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1281) l2cap_sock_teardown_cb (/v6.1-rc2/./include/net/bluetooth/bluetooth.h:304 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1475 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1612) l2cap_chan_close (/v6.1-rc2/net/bluetooth/l2cap_core.c:885) ? __kasan_check_write (/v6.1-rc2/mm/kasan/shadow.c:37) l2cap_sock_shutdown (/v6.1-rc2/./include/linux/kcsan-checks.h:231 /v6.1-rc2/./include/net/sock.h:2470 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1321 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1377) ? _raw_write_unlock (/v6.1-rc2/./include/asm-generic/qrwlock.h:122 /v6.1-rc2/./include/linux/rwlock_api_smp.h:225 /v6.1-rc2/kernel/locking/spinlock.c:342) l2cap_sock_release (/v6.1-rc2/net/bluetooth/l2cap_sock.c:1453) sock_close (/v6.1-rc2/net/socket.c:1382) ? sock_mmap (/v6.1-rc2/net/socket.c:?) __fput (/v6.1-rc2/./include/linux/fsnotify.h:? /v6.1-rc2/./include/linux/fsnotify.h:99 /v6.1-rc2/./include/linux/fsnotify.h:341 /v6.1-rc2/fs/file_table.c:306) ____fput (/v6.1-rc2/fs/file_table.c:348) task_work_run (/v6.1-rc2/kernel/task_work.c:165) do_exit (/v6.1-rc2/kernel/exit.c:?) do_group_exit (/v6.1-rc2/kernel/exit.c:943) ? __kasan_check_write (/v6.1-rc2/mm/kasan/shadow.c:37) get_signal (/v6.1-rc2/kernel/signal.c:2863) ? _raw_spin_unlock (/v6.1-rc2/./include/linux/spinlock_api_smp.h:142 /v6.1-rc2/kernel/locking/spinlock.c:186) ? finish_task_switch (/v6.1-rc2/./arch/x86/include/asm/current.h:15 /v6.1-rc2/kernel/sched/core.c:5065) arch_do_signal_or_restart (/v6.1-rc2/arch/x86/kernel/signal.c:869) exit_to_user_mode_prepare (/v6.1-rc2/kernel/entry/common.c:383) syscall_exit_to_user_mode (/v6.1-rc2/./arch/x86/include/asm/current.h:15 /v6.1-rc2/kernel/entry/common.c:261 /v6.1-rc2/kernel/entry/common.c:283 /v6.1-rc2/kernel/entry/common.c:296) do_syscall_64 (/v6.1-rc2/arch/x86/entry/common.c:50 /v6.1-rc2/arch/x86/entry/common.c:80) ? sysvec_apic_timer_interrupt (/v6.1-rc2/arch/x86/kernel/apic/apic.c:1107) entry_SYSCALL_64_after_hwframe (/v6.1-rc2/arch/x86/entry/entry_64.S:120) RIP: 0033:0x7f66c14db970 Code: Unable to access opcode bytes at 0x7f66c14db946. Code starting with the faulting instruction =========================================== RSP: 002b:00007ffe166a5508 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: 0000000000000013 RBX: 0000000000000013 RCX: 00007f66c14db970 RDX: 0000000000000013 RSI: 00007ffe166a56d0 RDI: 0000000000000002 RBP: 00007ffe166a56d0 R08: 00007f66c1a28440 R09: 0000000000000013 R10: 0000000000000078 R11: 0000000000000246 R12: 0000000000000013 R13: 0000000000000001 R14: 00007f66c179a520 R15: 0000000000000013 </TASK> Allocated by task 77: kasan_set_track (/v6.1-rc2/mm/kasan/common.c:51) kasan_save_alloc_info (/v6.1-rc2/mm/kasan/generic.c:432 /v6.1-rc2/mm/kasan/generic.c:498) __kasan_kmalloc (/v6.1-rc2/mm/kasan/common.c:356) __kmalloc (/v6.1-rc2/mm/slab_common.c:943 /v6.1-rc2/mm/slab_common.c:968) sk_prot_alloc (/v6.1-rc2/net/core/sock.c:2028) sk_alloc (/v6.1-rc2/net/core/sock.c:2083) l2cap_sock_alloc (/v6.1-rc2/net/bluetooth/l2cap_sock.c:1903) l2cap_sock_new_connection_cb (/v6.1-rc2/net/bluetooth/l2cap_sock.c:1504) l2cap_connect (/v6.1-rc2/net/bluetooth/l2cap_core.c:102 /v6.1-rc2/net/bluetooth/l2cap_core.c:4277) l2cap_bredr_sig_cmd (/v6.1-rc2/net/bluetooth/l2cap_core.c:5634 /v6.1-rc2/net/bluetooth/l2cap_core.c:5927) l2cap_recv_frame (/v6.1-rc2/net/bluetooth/l2cap_core.c:7851 /v6.1-rc2/net/bluetooth/l2cap_core.c:7919) l2cap_recv_acldata (/v6.1-rc2/net/bluetooth/l2cap_core.c:8601 /v6.1-rc2/net/bluetooth/l2cap_core.c:8631) hci_rx_work (/v6.1-rc2/./include/net/bluetooth/hci_core.h:1121 /v6.1-rc2/net/bluetooth/hci_core.c:3937 /v6.1-rc2/net/bluetooth/hci_core.c:4189) process_one_work (/v6.1-rc2/kernel/workqueue.c:2225) worker_thread (/v6.1-rc2/kernel/workqueue.c:816 /v6.1-rc2/kernel/workqueue.c:2107 /v6.1-rc2/kernel/workqueue.c:2159 /v6.1-rc2/kernel/workqueue.c:2408) kthread (/v6.1-rc2/kernel/kthread.c:361) ret_from_fork (/v6.1-rc2/arch/x86/entry/entry_64.S:306) Freed by task 52: kasan_set_track (/v6.1-rc2/mm/kasan/common.c:51) kasan_save_free_info (/v6.1-rc2/mm/kasan/generic.c:508) ____kasan_slab_free (/v6.1-rc2/./include/linux/slub_def.h:164 /v6.1-rc2/mm/kasan/common.c:214) __kasan_slab_free (/v6.1-rc2/mm/kasan/common.c:244) slab_free_freelist_hook (/v6.1-rc2/mm/slub.c:381 /v6.1-rc2/mm/slub.c:1747) __kmem_cache_free (/v6.1-rc2/mm/slub.c:3656 /v6.1-rc2/mm/slub.c:3674) kfree (/v6.1-rc2/mm/slab_common.c:1007) __sk_destruct (/v6.1-rc2/./include/linux/cred.h:288 /v6.1-rc2/net/core/sock.c:2147) __sk_free (/v6.1-rc2/./include/linux/sock_diag.h:87 /v6.1-rc2/net/core/sock.c:2175) sk_free (/v6.1-rc2/./include/linux/instrumented.h:? /v6.1-rc2/./include/linux/atomic/atomic-instrumented.h:176 /v6.1-rc2/./include/linux/refcount.h:272 /v6.1-rc2/./include/linux/refcount.h:315 /v6.1-rc2/./include/linux/refcount.h:333 /v6.1-rc2/net/core/sock.c:2188) l2cap_sock_kill (/v6.1-rc2/./include/net/bluetooth/bluetooth.h:286 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1284) l2cap_sock_close_cb (/v6.1-rc2/net/bluetooth/l2cap_sock.c:1576) l2cap_chan_timeout (/v6.1-rc2/./include/net/bluetooth/bluetooth.h:296 /v6.1-rc2/net/bluetooth/l2cap_core.c:462) process_one_work (/v6.1-rc2/kernel/workqueue.c:2225) worker_thread (/v6.1-rc2/kernel/workqueue.c:816 /v6.1-rc2/kernel/workqueue.c:2107 /v6.1-rc2/kernel/workqueue.c:2159 /v6.1-rc2/kernel/workqueue.c:2408) kthread (/v6.1-rc2/kernel/kthread.c:361) ret_from_fork (/v6.1-rc2/arch/x86/entry/entry_64.S:306) The buggy address belongs to the object at ffff88800f7f4000 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 96 bytes inside of 1024-byte region [ffff88800f7f4000, ffff88800f7f4400) The buggy address belongs to the physical page: page:00000000b8d65c1d refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88800f7f6800 pfn:0xf7f4 head:00000000b8d65c1d order:2 compound_mapcount:0 compound_pincount:0 flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff) raw: 000fffffc0010200 ffffea0000993408 ffffea0000991308 ffff888005841dc0 raw: ffff88800f7f6800 0000000000080002 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88800f7f3f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff88800f7f3f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff >ffff88800f7f4000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff88800f7f4080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88800f7f4100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== > > > > Context 2: > > l2cap_chan_timeout(); > > l2cap_chan_lock(chan); > > chan->ops->close(chan); > > l2cap_sock_close_cb() > > l2cap_sock_kill(sk); // <-- sk is freed here > > l2cap_chan_unlock(chan); > > > > Please add a Fixes: tag Fixes: 6c08fc896b60 ("Bluetooth: Fix refcount use-after-free issue") > > Signed-off-by: Sungwoo Kim <iam@sung-woo.kim> > > --- > > net/bluetooth/l2cap_sock.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c > > index ca8f07f35..657704059 100644 > > --- a/net/bluetooth/l2cap_sock.c > > +++ b/net/bluetooth/l2cap_sock.c > > @@ -1245,7 +1245,7 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, > > */ > > static void l2cap_sock_kill(struct sock *sk) > > { > > - if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) > > + if (!sk || !sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) > > return; > > > > BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state)); > > -- > > 2.25.1 > >
On Thu, Feb 2, 2023 at 1:09 PM Sungwoo Kim <iam@sung-woo.kim> wrote: > > On Thu, Feb 2, 2023 at 4:26 AM Eric Dumazet <edumazet@google.com> wrote: > > > > On Thu, Feb 2, 2023 at 10:07 AM Sungwoo Kim <iam@sung-woo.kim> wrote: > > > > > > Due to the race condition between l2cap_sock_cleanup_listen and > > > l2cap_sock_close_cb, l2cap_sock_kill can receive already freed sk, > > > resulting in use-after-free inside l2cap_sock_kill. > > > This patch prevent this by adding a null check in l2cap_sock_kill. > > > > > > Context 1: > > > l2cap_sock_cleanup_listen(); > > > // context switched > > > l2cap_chan_lock(chan); > > > l2cap_sock_kill(sk); // <-- sk is already freed below > > > > But sk is used in l2cap_sock_cleanup_listen() > > and should not be NULL... > > > > while ((sk = bt_accept_dequeue(parent, NULL))) { > > ... > > l2cap_sock_kill(sk); > > .. > > } > > > > It would help if you send us a stack trace ... > > Here is the stack trace and l2cap_sock.c: > https://gist.github.com/swkim101/5c3b8cb7c7d7172aef23810c9412f323 > > ================================================================== > BUG: KASAN: use-after-free in l2cap_sock_kill (/v6.1-rc2/./include/net/sock.h:986 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1281) > Read of size 8 at addr ffff88800f7f4060 by task l2cap-server/1764 > CPU: 0 PID: 1764 Comm: l2cap-server Not tainted 6.1.0-rc2 #129 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 > Call Trace: > <TASK> > dump_stack_lvl (/v6.1-rc2/lib/dump_stack.c:105) > print_address_description+0x7e/0x360 > print_report (/v6.1-rc2/mm/kasan/report.c:187 /v6.1-rc2/mm/kasan/report.c:389) > ? __virt_addr_valid (/v6.1-rc2/./include/linux/mmzone.h:1855 /v6.1-rc2/arch/x86/mm/physaddr.c:65) > ? kasan_complete_mode_report_info (/v6.1-rc2/mm/kasan/report_generic.c:104 /v6.1-rc2/mm/kasan/report_generic.c:127 /v6.1-rc2/mm/kasan/report_generic.c:136) > ? l2cap_sock_kill (/v6.1-rc2/./include/net/sock.h:986 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1281) > kasan_report (/v6.1-rc2/mm/kasan/report.c:? /v6.1-rc2/mm/kasan/report.c:484) > ? l2cap_sock_kill (/v6.1-rc2/./include/net/sock.h:986 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1281) > kasan_check_range (/v6.1-rc2/mm/kasan/generic.c:85 /v6.1-rc2/mm/kasan/generic.c:115 /v6.1-rc2/mm/kasan/generic.c:128 /v6.1-rc2/mm/kasan/generic.c:159 /v6.1-rc2/mm/kasan/generic.c:180 /v6.1-rc2/mm/kasan/generic.c:189) > __kasan_check_read (/v6.1-rc2/mm/kasan/shadow.c:31) > l2cap_sock_kill (/v6.1-rc2/./include/net/sock.h:986 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1281) > l2cap_sock_teardown_cb (/v6.1-rc2/./include/net/bluetooth/bluetooth.h:304 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1475 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1612) > l2cap_chan_close (/v6.1-rc2/net/bluetooth/l2cap_core.c:885) > ? __kasan_check_write (/v6.1-rc2/mm/kasan/shadow.c:37) > l2cap_sock_shutdown (/v6.1-rc2/./include/linux/kcsan-checks.h:231 /v6.1-rc2/./include/net/sock.h:2470 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1321 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1377) > ? _raw_write_unlock (/v6.1-rc2/./include/asm-generic/qrwlock.h:122 /v6.1-rc2/./include/linux/rwlock_api_smp.h:225 /v6.1-rc2/kernel/locking/spinlock.c:342) > l2cap_sock_release (/v6.1-rc2/net/bluetooth/l2cap_sock.c:1453) > sock_close (/v6.1-rc2/net/socket.c:1382) > ? sock_mmap (/v6.1-rc2/net/socket.c:?) > __fput (/v6.1-rc2/./include/linux/fsnotify.h:? /v6.1-rc2/./include/linux/fsnotify.h:99 /v6.1-rc2/./include/linux/fsnotify.h:341 /v6.1-rc2/fs/file_table.c:306) > ____fput (/v6.1-rc2/fs/file_table.c:348) > task_work_run (/v6.1-rc2/kernel/task_work.c:165) > do_exit (/v6.1-rc2/kernel/exit.c:?) > do_group_exit (/v6.1-rc2/kernel/exit.c:943) OK, now compare this trace with what you put in your changelog... Very different problem. Context 1: l2cap_sock_cleanup_listen(); // context switched l2cap_chan_lock(chan); l2cap_sock_kill(sk); // <-- sk is already freed below On current linux tree, all l2cap_sock_kill() callers already checked sk != NULL Do you have a repro ? > ? __kasan_check_write (/v6.1-rc2/mm/kasan/shadow.c:37) > get_signal (/v6.1-rc2/kernel/signal.c:2863) > ? _raw_spin_unlock (/v6.1-rc2/./include/linux/spinlock_api_smp.h:142 /v6.1-rc2/kernel/locking/spinlock.c:186) > ? finish_task_switch (/v6.1-rc2/./arch/x86/include/asm/current.h:15 /v6.1-rc2/kernel/sched/core.c:5065) > arch_do_signal_or_restart (/v6.1-rc2/arch/x86/kernel/signal.c:869) > exit_to_user_mode_prepare (/v6.1-rc2/kernel/entry/common.c:383) > syscall_exit_to_user_mode (/v6.1-rc2/./arch/x86/include/asm/current.h:15 /v6.1-rc2/kernel/entry/common.c:261 /v6.1-rc2/kernel/entry/common.c:283 /v6.1-rc2/kernel/entry/common.c:296) > do_syscall_64 (/v6.1-rc2/arch/x86/entry/common.c:50 /v6.1-rc2/arch/x86/entry/common.c:80) > ? sysvec_apic_timer_interrupt (/v6.1-rc2/arch/x86/kernel/apic/apic.c:1107) > entry_SYSCALL_64_after_hwframe (/v6.1-rc2/arch/x86/entry/entry_64.S:120) > RIP: 0033:0x7f66c14db970 > Code: Unable to access opcode bytes at 0x7f66c14db946. > > Code starting with the faulting instruction > =========================================== > RSP: 002b:00007ffe166a5508 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 > RAX: 0000000000000013 RBX: 0000000000000013 RCX: 00007f66c14db970 > RDX: 0000000000000013 RSI: 00007ffe166a56d0 RDI: 0000000000000002 > RBP: 00007ffe166a56d0 R08: 00007f66c1a28440 R09: 0000000000000013 > R10: 0000000000000078 R11: 0000000000000246 R12: 0000000000000013 > R13: 0000000000000001 R14: 00007f66c179a520 R15: 0000000000000013 > </TASK> > Allocated by task 77: > kasan_set_track (/v6.1-rc2/mm/kasan/common.c:51) > kasan_save_alloc_info (/v6.1-rc2/mm/kasan/generic.c:432 /v6.1-rc2/mm/kasan/generic.c:498) > __kasan_kmalloc (/v6.1-rc2/mm/kasan/common.c:356) > __kmalloc (/v6.1-rc2/mm/slab_common.c:943 /v6.1-rc2/mm/slab_common.c:968) > sk_prot_alloc (/v6.1-rc2/net/core/sock.c:2028) > sk_alloc (/v6.1-rc2/net/core/sock.c:2083) > l2cap_sock_alloc (/v6.1-rc2/net/bluetooth/l2cap_sock.c:1903) > l2cap_sock_new_connection_cb (/v6.1-rc2/net/bluetooth/l2cap_sock.c:1504) > l2cap_connect (/v6.1-rc2/net/bluetooth/l2cap_core.c:102 /v6.1-rc2/net/bluetooth/l2cap_core.c:4277) > l2cap_bredr_sig_cmd (/v6.1-rc2/net/bluetooth/l2cap_core.c:5634 /v6.1-rc2/net/bluetooth/l2cap_core.c:5927) > l2cap_recv_frame (/v6.1-rc2/net/bluetooth/l2cap_core.c:7851 /v6.1-rc2/net/bluetooth/l2cap_core.c:7919) > l2cap_recv_acldata (/v6.1-rc2/net/bluetooth/l2cap_core.c:8601 /v6.1-rc2/net/bluetooth/l2cap_core.c:8631) > hci_rx_work (/v6.1-rc2/./include/net/bluetooth/hci_core.h:1121 /v6.1-rc2/net/bluetooth/hci_core.c:3937 /v6.1-rc2/net/bluetooth/hci_core.c:4189) > process_one_work (/v6.1-rc2/kernel/workqueue.c:2225) > worker_thread (/v6.1-rc2/kernel/workqueue.c:816 /v6.1-rc2/kernel/workqueue.c:2107 /v6.1-rc2/kernel/workqueue.c:2159 /v6.1-rc2/kernel/workqueue.c:2408) > kthread (/v6.1-rc2/kernel/kthread.c:361) > ret_from_fork (/v6.1-rc2/arch/x86/entry/entry_64.S:306) > Freed by task 52: > kasan_set_track (/v6.1-rc2/mm/kasan/common.c:51) > kasan_save_free_info (/v6.1-rc2/mm/kasan/generic.c:508) > ____kasan_slab_free (/v6.1-rc2/./include/linux/slub_def.h:164 /v6.1-rc2/mm/kasan/common.c:214) > __kasan_slab_free (/v6.1-rc2/mm/kasan/common.c:244) > slab_free_freelist_hook (/v6.1-rc2/mm/slub.c:381 /v6.1-rc2/mm/slub.c:1747) > __kmem_cache_free (/v6.1-rc2/mm/slub.c:3656 /v6.1-rc2/mm/slub.c:3674) > kfree (/v6.1-rc2/mm/slab_common.c:1007) > __sk_destruct (/v6.1-rc2/./include/linux/cred.h:288 /v6.1-rc2/net/core/sock.c:2147) > __sk_free (/v6.1-rc2/./include/linux/sock_diag.h:87 /v6.1-rc2/net/core/sock.c:2175) > sk_free (/v6.1-rc2/./include/linux/instrumented.h:? /v6.1-rc2/./include/linux/atomic/atomic-instrumented.h:176 /v6.1-rc2/./include/linux/refcount.h:272 /v6.1-rc2/./include/linux/refcount.h:315 /v6.1-rc2/./include/linux/refcount.h:333 /v6.1-rc2/net/core/sock.c:2188) > l2cap_sock_kill (/v6.1-rc2/./include/net/bluetooth/bluetooth.h:286 /v6.1-rc2/net/bluetooth/l2cap_sock.c:1284) > l2cap_sock_close_cb (/v6.1-rc2/net/bluetooth/l2cap_sock.c:1576) > l2cap_chan_timeout (/v6.1-rc2/./include/net/bluetooth/bluetooth.h:296 /v6.1-rc2/net/bluetooth/l2cap_core.c:462) > process_one_work (/v6.1-rc2/kernel/workqueue.c:2225) > worker_thread (/v6.1-rc2/kernel/workqueue.c:816 /v6.1-rc2/kernel/workqueue.c:2107 /v6.1-rc2/kernel/workqueue.c:2159 /v6.1-rc2/kernel/workqueue.c:2408) > kthread (/v6.1-rc2/kernel/kthread.c:361) > ret_from_fork (/v6.1-rc2/arch/x86/entry/entry_64.S:306) > The buggy address belongs to the object at ffff88800f7f4000 > which belongs to the cache kmalloc-1k of size 1024 > The buggy address is located 96 bytes inside of > 1024-byte region [ffff88800f7f4000, ffff88800f7f4400) > The buggy address belongs to the physical page: > page:00000000b8d65c1d refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88800f7f6800 pfn:0xf7f4 > head:00000000b8d65c1d order:2 compound_mapcount:0 compound_pincount:0 > flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff) > raw: 000fffffc0010200 ffffea0000993408 ffffea0000991308 ffff888005841dc0 > raw: ffff88800f7f6800 0000000000080002 00000001ffffffff 0000000000000000 > page dumped because: kasan: bad access detected > Memory state around the buggy address: > ffff88800f7f3f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > ffff88800f7f3f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > >ffff88800f7f4000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > ^ > ffff88800f7f4080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > ffff88800f7f4100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > ================================================================== > > > > > > > Context 2: > > > l2cap_chan_timeout(); > > > l2cap_chan_lock(chan); > > > chan->ops->close(chan); > > > l2cap_sock_close_cb() > > > l2cap_sock_kill(sk); // <-- sk is freed here > > > l2cap_chan_unlock(chan); > > > > > > > Please add a Fixes: tag > > Fixes: 6c08fc896b60 ("Bluetooth: Fix refcount use-after-free issue") > > > Signed-off-by: Sungwoo Kim <iam@sung-woo.kim> > > > --- > > > net/bluetooth/l2cap_sock.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c > > > index ca8f07f35..657704059 100644 > > > --- a/net/bluetooth/l2cap_sock.c > > > +++ b/net/bluetooth/l2cap_sock.c > > > @@ -1245,7 +1245,7 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, > > > */ > > > static void l2cap_sock_kill(struct sock *sk) > > > { > > > - if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) > > > + if (!sk || !sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) > > > return; > > > > > > BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state)); > > > -- > > > 2.25.1 > > >
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index ca8f07f35..657704059 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1245,7 +1245,7 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, */ static void l2cap_sock_kill(struct sock *sk) { - if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) + if (!sk || !sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));