Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp1497305iob; Fri, 29 Apr 2022 06:42:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy3rNmFg3f9ULcwqh2UNnaCMbeKILhLvkcTq5UwPKTp6+nTwSBkk0EOWCpHzvb+RyuIqEA+ X-Received: by 2002:ac2:4c54:0:b0:472:2323:f4e0 with SMTP id o20-20020ac24c54000000b004722323f4e0mr12023091lfk.295.1651239758400; Fri, 29 Apr 2022 06:42:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651239758; cv=none; d=google.com; s=arc-20160816; b=cQe7BNrI7bbsdjlqOZyhCSzX2h5oDLkE+sA+L2Gb08weqls2Vi4uK68re+T7JgoPhM zehwuI0f3abtSLF/fQvu7O5CIv3dOmqgkiyLMvFDnTHMJu7KBNefuonptZlZxFmhmjHi vW3mA3V/in8VX7UBreoFtUoUM4Pe/lBhpuyWcyVQMM5g42HbfAOctRY5kMfxFDhPo2f1 BeqUsJ0UDR9hRj1lGY0be9AhpstIQme99s0BX+OAwCxIhV7lIz+zV027Gzw/LhxgMs7M QeoKBj5n5p5SkwKYgkeRaB1W2c3OPd8gGJKvHFDOWDDaD6pw4qNzYAhymdD9LIUdnKkT WSYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from:cc :references:to:content-language:subject:user-agent:mime-version:date :message-id; bh=bFX4PUYSydgHUwn2qniv8IfbynxY/d56B7K3CMOoXhY=; b=juq4P6Lfa8O0wndJjvWzGmNtUVWQYyx7eQDbj0PQGYySdjw7YnPps/ouwAT2C7BYG+ kT9Oe+tKWG9gKowqNnoFfQE7TTygJCkaaFn1+YOroSQ8NMIgbW/xtuwi77qLuCj04nri m2Y9cqayeF5Kf8DCZ+uxXp/j6chWVipMPSkQXpqyUK27ieIXT1ealn/z73aJVV4f3BQS OGlF+OsGez/dLf+nDbI+QajkHZ6RZM/GFQkK7O7N6YWBwzHW+4FMfmc9UWoE7xcOnsLi PfnWXO6NaQH0kTlLJUFSMazV7+lk+QrozibdAbBnFc3ITC24Y9c4wuHyvtJYxqrwLXHr E2/g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p20-20020a056512235400b0044a30dc62bcsi7279530lfu.606.2022.04.29.06.42.17; Fri, 29 Apr 2022 06:42:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-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-wireless-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231432AbiD2LWX (ORCPT + 68 others); Fri, 29 Apr 2022 07:22:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230352AbiD2LWW (ORCPT ); Fri, 29 Apr 2022 07:22:22 -0400 Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37F6585675 for ; Fri, 29 Apr 2022 04:19:05 -0700 (PDT) Received: from fsav119.sakura.ne.jp (fsav119.sakura.ne.jp [27.133.134.246]) by www262.sakura.ne.jp (8.15.2/8.15.2) with ESMTP id 23TBIQZL003504; Fri, 29 Apr 2022 20:18:26 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav119.sakura.ne.jp (F-Secure/fsigk_smtp/550/fsav119.sakura.ne.jp); Fri, 29 Apr 2022 20:18:26 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/550/fsav119.sakura.ne.jp) Received: from [192.168.1.9] (M106072142033.v4.enabler.ne.jp [106.72.142.33]) (authenticated bits=0) by www262.sakura.ne.jp (8.15.2/8.15.2) with ESMTPSA id 23TBIPiV003500 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NO); Fri, 29 Apr 2022 20:18:26 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Message-ID: <3ec24824-00b6-4fc3-8bcf-71b9bbcb69c2@I-love.SAKURA.ne.jp> Date: Fri, 29 Apr 2022 20:18:21 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.8.1 Subject: [PATCH] ath9k: fix use-after-free read at ath9k_hif_usb_rx_cb() Content-Language: en-US To: Toke Hoiland-Jorgensen , Jakub Kicinski , Kalle Valo , "David S. Miller" , Eric Dumazet , Paolo Abeni , Pavel Skripkin References: <00000000000055348705b43c701d@google.com> Cc: syzbot , andreyknvl@google.com, ath9k-devel@qca.qualcomm.com, linux-usb@vger.kernel.org, linux-wireless@vger.kernel.org, syzkaller-bugs@googlegroups.com From: Tetsuo Handa In-Reply-To: <00000000000055348705b43c701d@google.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_NONE autolearn=unavailable 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-wireless@vger.kernel.org Although hif_dev->htc_handle is allocated by ath9k_htc_hw_alloc() from ath9k_hif_usb_firmware_cb(), hif_dev->htc_handle->drv_priv is not assigned until ieee80211_alloc_hw() from ath9k_htc_probe_device() from ath9k_htc_hw_init() from ath9k_hif_usb_firmware_cb() returns. However, as soon as ath9k_hif_usb_alloc_rx_urbs() from ath9k_hif_usb_alloc_urbs() from ath9k_hif_usb_dev_init() from ath9k_hif_usb_firmware_cb() returns, a timer interrupt can access hif_dev->htc_handle->drv_priv via RX_STAT_INC() from ath9k_hif_usb_rx_stream() from ath9k_hif_usb_rx_cb() from usb_hcd_giveback_urb(), which results in NULL pointer deference problem. Also, even after htc_handle->drv_priv is assigned, when ath9k_htc_wait_for_target() from ath9k_htc_probe_device() from ath9k_htc_hw_init() from ath9k_hif_usb_firmware_cb() fails, ieee80211_free_hw() (which does not reset hif_dev->htc_handle->drv_priv) is immediately called due to "goto err_free;". As a result, a timer interrupt which happens after ieee80211_free_hw() triggers use-after-free problem at the abovementioned location. We can flush in-flight requests by calling ath9k_hif_usb_dealloc_urbs() before calling ieee80211_free_hw(). But we need to take from two choices for not yet assigned case. One is to change e.g. RX_STAT_INC() to check for NULL because it depends on CONFIG_ATH9K_HTC_DEBUGFS=y. The other is to assign a dummy object which is used until initialization. This patch took the latter. Link: https://syzkaller.appspot.com/bug?extid=03110230a11411024147 Reported-by: syzbot Signed-off-by: Tetsuo Handa Tested-by: syzbot --- Pavel Skripkin has tested "check for NULL" approach, but not yet accepted. What was wrong with Pavel's approach? drivers/net/wireless/ath/ath9k/htc_drv_init.c | 6 +++--- drivers/net/wireless/ath/ath9k/htc_hst.c | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index ff61ae34ecdf..e497a44aff88 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -931,7 +931,6 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, u16 devid, char *product, u32 drv_info) { - struct hif_device_usb *hif_dev; struct ath9k_htc_priv *priv; struct ieee80211_hw *hw; int ret; @@ -969,10 +968,11 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, err_init: ath9k_stop_wmi(priv); - hif_dev = (struct hif_device_usb *)htc_handle->hif_dev; - ath9k_hif_usb_dealloc_urbs(hif_dev); + ath9k_hif_usb_dealloc_urbs((struct hif_device_usb *)htc_handle->hif_dev); ath9k_destroy_wmi(priv); err_free: + ath9k_hif_usb_dealloc_urbs((struct hif_device_usb *)htc_handle->hif_dev); + htc_handle->drv_priv = NULL; ieee80211_free_hw(hw); return ret; } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 994ec48b2f66..d461eca389ab 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -468,6 +468,9 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle, } } +/* A dummy object used until device is initialized. */ +static struct ath9k_htc_priv ath9k_uninitialized_htc_priv; + struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, struct ath9k_htc_hif *hif, struct device *dev) @@ -493,6 +496,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, atomic_set(&target->tgt_ready, 0); + target->drv_priv = &ath9k_uninitialized_htc_priv; + return target; } -- 2.34.1