From nobody Tue Dec 16 12:35:42 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F90AC4332F for ; Thu, 13 Oct 2022 17:55:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230084AbiJMRzb (ORCPT ); Thu, 13 Oct 2022 13:55:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230004AbiJMRyY (ORCPT ); Thu, 13 Oct 2022 13:54:24 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1651115380F; Thu, 13 Oct 2022 10:53:49 -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 ams.source.kernel.org (Postfix) with ESMTPS id A5AB4B82025; Thu, 13 Oct 2022 17:53:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F1CD3C433D6; Thu, 13 Oct 2022 17:53:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1665683627; bh=1Ll6/7ocjbBrCFkgVE7FHQn8nDSrcLDqlbjznr3zqsM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N3CEH3Ud/FqaCW7otzq54DeAQqg02A6VJUkwRg8/zaUp8YlUMjTbA3Ttsgu26Q0GR t1K8nopVwPWDaAKid8dRiSpkbPcB6PJaKsfSs566eEHDzgKjjo/zef/x86FMqfLlzz K4HmwBYiLPGpbpLshsozM/WvfAQDU8sBaTQoRzY0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, =?UTF-8?q?S=C3=B6nke=20Huster?= , Johannes Berg Subject: [PATCH 5.4 33/38] wifi: cfg80211: fix BSS refcounting bugs Date: Thu, 13 Oct 2022 19:52:34 +0200 Message-Id: <20221013175145.345782325@linuxfoundation.org> X-Mailer: git-send-email 2.38.0 In-Reply-To: <20221013175144.245431424@linuxfoundation.org> References: <20221013175144.245431424@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Johannes Berg commit 0b7808818cb9df6680f98996b8e9a439fa7bcc2f upstream. There are multiple refcounting bugs related to multi-BSSID: - In bss_ref_get(), if the BSS has a hidden_beacon_bss, then the bss pointer is overwritten before checking for the transmitted BSS, which is clearly wrong. Fix this by using the bss_from_pub() macro. - In cfg80211_bss_update() we copy the transmitted_bss pointer from tmp into new, but then if we release new, we'll unref it erroneously. We already set the pointer and ref it, but need to NULL it since it was copied from the tmp data. - In cfg80211_inform_single_bss_data(), if adding to the non- transmitted list fails, we unlink the BSS and yet still we return it, but this results in returning an entry without a reference. We shouldn't return it anyway if it was broken enough to not get added there. This fixes CVE-2022-42720. Reported-by: S=C3=B6nke Huster Tested-by: S=C3=B6nke Huster Fixes: a3584f56de1c ("cfg80211: Properly track transmitting and non-transmi= tting BSS") Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/wireless/scan.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -104,18 +104,12 @@ static inline void bss_ref_get(struct cf lockdep_assert_held(&rdev->bss_lock); =20 bss->refcount++; - if (bss->pub.hidden_beacon_bss) { - bss =3D container_of(bss->pub.hidden_beacon_bss, - struct cfg80211_internal_bss, - pub); - bss->refcount++; - } - if (bss->pub.transmitted_bss) { - bss =3D container_of(bss->pub.transmitted_bss, - struct cfg80211_internal_bss, - pub); - bss->refcount++; - } + + if (bss->pub.hidden_beacon_bss) + bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++; + + if (bss->pub.transmitted_bss) + bss_from_pub(bss->pub.transmitted_bss)->refcount++; } =20 static inline void bss_ref_put(struct cfg80211_registered_device *rdev, @@ -1233,6 +1227,8 @@ cfg80211_bss_update(struct cfg80211_regi new->refcount =3D 1; INIT_LIST_HEAD(&new->hidden_list); INIT_LIST_HEAD(&new->pub.nontrans_list); + /* we'll set this later if it was non-NULL */ + new->pub.transmitted_bss =3D NULL; =20 if (rcu_access_pointer(tmp->pub.proberesp_ies)) { hidden =3D rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); @@ -1462,10 +1458,15 @@ cfg80211_inform_single_bss_data(struct w spin_lock_bh(&rdev->bss_lock); if (cfg80211_add_nontrans_list(non_tx_data->tx_bss, &res->pub)) { - if (__cfg80211_unlink_bss(rdev, res)) + if (__cfg80211_unlink_bss(rdev, res)) { rdev->bss_generation++; + res =3D NULL; + } } spin_unlock_bh(&rdev->bss_lock); + + if (!res) + return NULL; } =20 trace_cfg80211_return_bss(&res->pub);