Received: by 2002:ac0:e34a:0:0:0:0:0 with SMTP id g10csp580516imn; Thu, 28 Jul 2022 09:29:18 -0700 (PDT) X-Google-Smtp-Source: AGRyM1t+6CiBL0QcAE+q8K/g0IirU0pU6NYmDj8QYmkxMjmj7AkyxtUaESxTK+xAC5i8gOWuDQIx X-Received: by 2002:a17:903:260b:b0:16d:a7a5:c3be with SMTP id jd11-20020a170903260b00b0016da7a5c3bemr11215859plb.154.1659025758594; Thu, 28 Jul 2022 09:29:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659025758; cv=none; d=google.com; s=arc-20160816; b=UbDVMWe+M4hYJsxfzam4H00iH7EkTFFQ9/nC1vqeu7oPGpSk+esekivNuwQgFYX6En 2yEF/pNA26MJnDq+5gFjtm6CB6V4hArXErzOHTKj/4kaMQdgRK8plPeRClruEIoI1s3w 6i7Al9I3a/W52jVBfYNzyIRIUC2APAtmozeqBKOIK/L6VlbD/v4EGPcacbsXenZx67Fq R3aYRnRqJzCMjajmu5uiBEdSzNnHJYrLnn91X9j9TAMyY5s08TvKZu8gclNsrEtE47kN r/2tJTFS2InExSzfAEGcAigol8PEaDhJUkz0pF+LHaMA3OfQ0PjeQAl+NK0RBN2VctpX w9rw== 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 :message-id:date:subject:cc:to:from; bh=SoEylRu2JZNGveg2l1EgbLF6+WC3xfHsu468ppArRko=; b=rQHxpl4uU8aHLhaQnyxD6MN/AHyR2okjtUaNNptdDBw9/fsanNTbjSOF5VVYuQd3C5 ikNaOCRmJ2Tj66F0ecC3jzlciEGpnBwwkj7WcWaV6UvadDEbtxPcZeG0esnrAN+8kqil AMOlKLnZTH7AC0/8V5tArn9DxHtx4AEpvfUVugIarg+V9khtKu7TgvIuW7EEXV263Pi5 +kWQ95NR0UXV2dgLeBOOve3JlMVLqzoJ2GHt03qmBHxpwCvt/ruEmHbq/lAdZkan8WU/ KPro2gl25oZLQPnFTGPO7K3Z5aEDSTbdzRi/AYCvWQN5y2sHEx1604Y6biHmwa3r5Wau 2cXQ== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ispras.ru Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c2-20020a170902c1c200b0016d12d40615si1223068plc.544.2022.07.28.09.29.02; Thu, 28 Jul 2022 09:29:18 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ispras.ru Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230010AbiG1QWU (ORCPT + 65 others); Thu, 28 Jul 2022 12:22:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229631AbiG1QWT (ORCPT ); Thu, 28 Jul 2022 12:22:19 -0400 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA81C6FA3C; Thu, 28 Jul 2022 09:22:17 -0700 (PDT) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 1074140755C7; Thu, 28 Jul 2022 16:22:16 +0000 (UTC) From: Fedor Pchelkin To: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , Kalle Valo Cc: Fedor Pchelkin , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , "John W. Linville" , Sujith Manoharan , linux-wireless@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Alexey Khoroshilov , ldv-project@linuxtesting.org Subject: [PATCH] ath9k: hif_usb: Fix use-after-free in ath9k_hif_usb_reg_in_cb() Date: Thu, 28 Jul 2022 19:21:49 +0300 Message-Id: <20220728162149.212306-1-pchelkin@ispras.ru> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS 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-wireless@vger.kernel.org It is possible that skb is freed in ath9k_htc_rx_msg(), then usb_submit_urb() fails and we try to free skb again. It causes use-after-free bug. Moreover, if alloc_skb() fails, urb->context becomes NULL but rx_buf is not freed and there can be a memory leak. The patch removes unnecessary nskb and makes skb processing more clear: it is supposed that ath9k_htc_rx_msg() either frees old skb or passes its managing to another callback function. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 3deff76095c4 ("ath9k_htc: Increase URB count for REG_IN pipe") Signed-off-by: Fedor Pchelkin Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/ath/ath9k/hif_usb.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 518deb5098a2..b70128d1594d 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -708,14 +708,13 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) struct rx_buf *rx_buf = (struct rx_buf *)urb->context; struct hif_device_usb *hif_dev = rx_buf->hif_dev; struct sk_buff *skb = rx_buf->skb; - struct sk_buff *nskb; int ret; if (!skb) return; if (!hif_dev) - goto free; + goto free_skb; switch (urb->status) { case 0: @@ -724,7 +723,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) case -ECONNRESET: case -ENODEV: case -ESHUTDOWN: - goto free; + goto free_skb; default: skb_reset_tail_pointer(skb); skb_trim(skb, 0); @@ -740,20 +739,19 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) skb->len, USB_REG_IN_PIPE); - nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC); - if (!nskb) { + skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC); + if (!skb) { dev_err(&hif_dev->udev->dev, "ath9k_htc: REG_IN memory allocation failure\n"); - urb->context = NULL; - return; + goto free_rx_buf; } - rx_buf->skb = nskb; + rx_buf->skb = skb; usb_fill_int_urb(urb, hif_dev->udev, usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), - nskb->data, MAX_REG_IN_BUF_SIZE, + skb->data, MAX_REG_IN_BUF_SIZE, ath9k_hif_usb_reg_in_cb, rx_buf, 1); } @@ -762,12 +760,13 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { usb_unanchor_urb(urb); - goto free; + goto free_skb; } return; -free: +free_skb: kfree_skb(skb); +free_rx_buf: kfree(rx_buf); urb->context = NULL; } -- 2.25.1