Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp4447831pxb; Wed, 20 Apr 2022 03:32:45 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyzSWnRWG+pUtqO7HJgz6cgEDOMMzTeuzdhoSs8dyBieBPVRi4OMGDjk3Td61b8QltwZVP2 X-Received: by 2002:a63:4b5d:0:b0:3aa:2a17:f7ff with SMTP id k29-20020a634b5d000000b003aa2a17f7ffmr8446456pgl.538.1650450764849; Wed, 20 Apr 2022 03:32:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650450764; cv=none; d=google.com; s=arc-20160816; b=KsxDzKItif8+plqhjVuFYZKMZoNWZo1bbigiRV3tN4aI6uLYtMYfIFTeDDPNFfwfl7 m8Qdcg82LZQuKQi4AcsLrxnQ0QnrmA/ZFgQjpqyYhZQ/oxqukzUnnZUIRfo/Q2bD0dE8 kH/n8FHmk3qwlxBgYliym1RCpXP4WdHUi/N1wIoqlNDKuGCQOKRXPD6TXCXKINuH10O9 xkVdA2Y+1nCgMHRKDxnjFGbAhSRLQ8kIOQfHtBJ6eZMZkZddgne2erN/X4yoNfLK7VUT LdaXQXZtM09xmiptkNDxoKPqrhpdpgBUkLpzNwQ9SUhW1HV1tNcwoILf2QP8nLzez7r6 Zv9g== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=1DRGLroNvAtU9Mht7ay1zQdm25s3eJAm/N5y/IDcOLc=; b=O47E1Jh/aOBaW5oDUje6YHlZAjlCKvENIHH56rc9AYR+kxXwm6oRggrqxCLKsbhY// 5kShCuziQ8GGaYiEO4PPwVDzEPmROjwcLsjLy3Uk+kOs6jpguvCRZArMdbdVgIKx3ato K1eyAFKSJBmR4Pp0RO1lGwLqMc04d8fymzmRcMBgmRPYWNtSxVc0Wck7AufrgA7oeaK4 YYG/bpTju9vt6D1LL4nVBDPiBqKNNJiRA1Zhuww7OkUyA4EMNbtrcVW7eRDlllnGxZU1 l3LVTG4C29JV+gT8q70t4c5/aLknEFZkXtDxmLrQU4N8oACTkjLeUGvx5rQ1MIKRBQAz 0OgQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=icok8PLV; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c4-20020a170903234400b001590118e14dsi1938182plh.108.2022.04.20.03.32.29; Wed, 20 Apr 2022 03:32:44 -0700 (PDT) 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; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=icok8PLV; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242066AbiDRNcP (ORCPT + 99 others); Mon, 18 Apr 2022 09:32:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239507AbiDRNFp (ORCPT ); Mon, 18 Apr 2022 09:05:45 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3CE729CB5; Mon, 18 Apr 2022 05:46:40 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5EC9660FB6; Mon, 18 Apr 2022 12:46:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 51E01C385A7; Mon, 18 Apr 2022 12:46:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1650285999; bh=gEhd9SIx2dQ77qkb2YCf5p7Rcp+rG4I7/rBY2UZDcgA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=icok8PLV7IjmEjwIGAgnBIZwF+QOAwq0EGlUk65BlIjSc/7pQHF0k/anbTr4iWIuG J0PG2x7IwgV8/XFaTiaSxM5Tf5SrZuz0l0uz4ZPBsdcQnnxBUoony5poKwSDKM79MO Uu+3m8DQGEL/9i4oTBXy12w3xYy4NG4OZqU0ZWSs= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lin Ma , Krzysztof Kozlowski , "David S. Miller" , Sasha Levin Subject: [PATCH 4.19 09/32] nfc: nci: add flush_workqueue to prevent uaf Date: Mon, 18 Apr 2022 14:13:49 +0200 Message-Id: <20220418121127.399707232@linuxfoundation.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220418121127.127656835@linuxfoundation.org> References: <20220418121127.127656835@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham 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: X-Mailing-List: linux-kernel@vger.kernel.org From: Lin Ma [ Upstream commit ef27324e2cb7bb24542d6cb2571740eefe6b00dc ] Our detector found a concurrent use-after-free bug when detaching an NCI device. The main reason for this bug is the unexpected scheduling between the used delayed mechanism (timer and workqueue). The race can be demonstrated below: Thread-1 Thread-2 | nci_dev_up() | nci_open_device() | __nci_request(nci_reset_req) | nci_send_cmd | queue_work(cmd_work) nci_unregister_device() | nci_close_device() | ... del_timer_sync(cmd_timer)[1] | ... | Worker nci_free_device() | nci_cmd_work() kfree(ndev)[3] | mod_timer(cmd_timer)[2] In short, the cleanup routine thought that the cmd_timer has already been detached by [1] but the mod_timer can re-attach the timer [2], even it is already released [3], resulting in UAF. This UAF is easy to trigger, crash trace by POC is like below [ 66.703713] ================================================================== [ 66.703974] BUG: KASAN: use-after-free in enqueue_timer+0x448/0x490 [ 66.703974] Write of size 8 at addr ffff888009fb7058 by task kworker/u4:1/33 [ 66.703974] [ 66.703974] CPU: 1 PID: 33 Comm: kworker/u4:1 Not tainted 5.18.0-rc2 #5 [ 66.703974] Workqueue: nfc2_nci_cmd_wq nci_cmd_work [ 66.703974] Call Trace: [ 66.703974] [ 66.703974] dump_stack_lvl+0x57/0x7d [ 66.703974] print_report.cold+0x5e/0x5db [ 66.703974] ? enqueue_timer+0x448/0x490 [ 66.703974] kasan_report+0xbe/0x1c0 [ 66.703974] ? enqueue_timer+0x448/0x490 [ 66.703974] enqueue_timer+0x448/0x490 [ 66.703974] __mod_timer+0x5e6/0xb80 [ 66.703974] ? mark_held_locks+0x9e/0xe0 [ 66.703974] ? try_to_del_timer_sync+0xf0/0xf0 [ 66.703974] ? lockdep_hardirqs_on_prepare+0x17b/0x410 [ 66.703974] ? queue_work_on+0x61/0x80 [ 66.703974] ? lockdep_hardirqs_on+0xbf/0x130 [ 66.703974] process_one_work+0x8bb/0x1510 [ 66.703974] ? lockdep_hardirqs_on_prepare+0x410/0x410 [ 66.703974] ? pwq_dec_nr_in_flight+0x230/0x230 [ 66.703974] ? rwlock_bug.part.0+0x90/0x90 [ 66.703974] ? _raw_spin_lock_irq+0x41/0x50 [ 66.703974] worker_thread+0x575/0x1190 [ 66.703974] ? process_one_work+0x1510/0x1510 [ 66.703974] kthread+0x2a0/0x340 [ 66.703974] ? kthread_complete_and_exit+0x20/0x20 [ 66.703974] ret_from_fork+0x22/0x30 [ 66.703974] [ 66.703974] [ 66.703974] Allocated by task 267: [ 66.703974] kasan_save_stack+0x1e/0x40 [ 66.703974] __kasan_kmalloc+0x81/0xa0 [ 66.703974] nci_allocate_device+0xd3/0x390 [ 66.703974] nfcmrvl_nci_register_dev+0x183/0x2c0 [ 66.703974] nfcmrvl_nci_uart_open+0xf2/0x1dd [ 66.703974] nci_uart_tty_ioctl+0x2c3/0x4a0 [ 66.703974] tty_ioctl+0x764/0x1310 [ 66.703974] __x64_sys_ioctl+0x122/0x190 [ 66.703974] do_syscall_64+0x3b/0x90 [ 66.703974] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 66.703974] [ 66.703974] Freed by task 406: [ 66.703974] kasan_save_stack+0x1e/0x40 [ 66.703974] kasan_set_track+0x21/0x30 [ 66.703974] kasan_set_free_info+0x20/0x30 [ 66.703974] __kasan_slab_free+0x108/0x170 [ 66.703974] kfree+0xb0/0x330 [ 66.703974] nfcmrvl_nci_unregister_dev+0x90/0xd0 [ 66.703974] nci_uart_tty_close+0xdf/0x180 [ 66.703974] tty_ldisc_kill+0x73/0x110 [ 66.703974] tty_ldisc_hangup+0x281/0x5b0 [ 66.703974] __tty_hangup.part.0+0x431/0x890 [ 66.703974] tty_release+0x3a8/0xc80 [ 66.703974] __fput+0x1f0/0x8c0 [ 66.703974] task_work_run+0xc9/0x170 [ 66.703974] exit_to_user_mode_prepare+0x194/0x1a0 [ 66.703974] syscall_exit_to_user_mode+0x19/0x50 [ 66.703974] do_syscall_64+0x48/0x90 [ 66.703974] entry_SYSCALL_64_after_hwframe+0x44/0xae To fix the UAF, this patch adds flush_workqueue() to ensure the nci_cmd_work is finished before the following del_timer_sync. This combination will promise the timer is actually detached. Fixes: 6a2968aaf50c ("NFC: basic NCI protocol implementation") Signed-off-by: Lin Ma Reviewed-by: Krzysztof Kozlowski Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/nfc/nci/core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 0e0dff72a9e4..0580e5326641 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -560,6 +560,10 @@ static int nci_close_device(struct nci_dev *ndev) mutex_lock(&ndev->req_lock); if (!test_and_clear_bit(NCI_UP, &ndev->flags)) { + /* Need to flush the cmd wq in case + * there is a queued/running cmd_work + */ + flush_workqueue(ndev->cmd_wq); del_timer_sync(&ndev->cmd_timer); del_timer_sync(&ndev->data_timer); mutex_unlock(&ndev->req_lock); -- 2.35.1