From patchwork Thu Mar 15 07:29:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 10283971 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B8FA1602C2 for ; Thu, 15 Mar 2018 07:30:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7A83288E7 for ; Thu, 15 Mar 2018 07:30:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 97D4D288D7; Thu, 15 Mar 2018 07:30:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 90CFD288E7 for ; Thu, 15 Mar 2018 07:30:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751542AbeCOHa1 (ORCPT ); Thu, 15 Mar 2018 03:30:27 -0400 Received: from mail-lf0-f52.google.com ([209.85.215.52]:33535 "EHLO mail-lf0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750950AbeCOHa0 (ORCPT ); Thu, 15 Mar 2018 03:30:26 -0400 Received: by mail-lf0-f52.google.com with SMTP id x205-v6so8642963lfa.0; Thu, 15 Mar 2018 00:30:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=K3zZ8XdMGYuIDZpIwb9deKZBfZWSE25kVUatwiDgSvc=; b=NtalbmtMLpVBPMWnlTpPkOe2wpIkQu739MopSGft1IuOn8s8HAL2vqXlEQ9Y1kAYVs 7OdsmkxMbh88EP7xKjl0JYRS/6ykyGT3JTHBZ/4l5Sert9/g5v6UjQbiQI+mK6O4edyf 6dnkBglupBU0nQxg0+/B1MUhKF657t7mIZ56AjJKLLhZE6jOMieO3lhJ9X0uL414ca1H oFzq0j0kml3iUwBvrZBdzd3I6YmXBUi9RF9oBef2pd3uxPb77njQQtX/YAQcNRLPz6+T XiQuWHUUQgPBJXNwq6dDTSFyVchuxGTes6vqgzQZDhAPjXoaC0vQwJIKsNmJzuxSrlo/ dxIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=K3zZ8XdMGYuIDZpIwb9deKZBfZWSE25kVUatwiDgSvc=; b=WIrc9kkUOt2Cxngf+3U1I6/LQjb0XNBy5l8f1hBg8Wz8aA+bWAx7j2zlBCt3m/XLK0 sbQUd/KpWmJLpindoqlHZdKd5/BvwdRPSxxvy3HSRCraxftB1y3fd8t1irvqvTyEbOi+ ooJm9QaGKFfM0ZuUP4A9K7AYZjMFmtc/8Ri2NC5oeFAb1SWijGAnONVSehEZN8P6FJzg fLRmKUHPvABcxCsjIF/pTZdh5QV6ISNpQkYyvqPlERU1HeE1O5x3gQmqQ3Gfu670x1ir qEN8hw2UMiZuIJQ/m7e9TaqdaKO0c2PewutGa44ofZ6gTxcYjiIxy8axRo8F8OC7ZLrp 4Nog== X-Gm-Message-State: AElRT7Ha0W2ZuZap8+CJB4udyEr7KUm9kpxWkkg/nL0ZnMKxeLWvPGXL wOZTl9a0zPaDXwZAJlFrQvg= X-Google-Smtp-Source: AG47ELuCRpYnYvTBDHxhUUDl1a9mOO3eQ6no75zCE6chWmqJx+EV03Yk2OnHl4yuZl3dnQiVPbbelQ== X-Received: by 10.46.146.25 with SMTP id k25mr546372ljg.100.1521099024240; Thu, 15 Mar 2018 00:30:24 -0700 (PDT) Received: from linux-samsung.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.gmail.com with ESMTPSA id i62-v6sm1045289lfa.45.2018.03.15.00.30.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Mar 2018 00:30:23 -0700 (PDT) From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= To: Kalle Valo Cc: Arend van Spriel , Franky Lin , Hante Meuleman , Chi-Hsien Lin , Wright Feng , Pieter-Paul Giesberts , James Hughes , linux-wireless@vger.kernel.org, brcm80211-dev-list.pdl@broadcom.com, brcm80211-dev-list@cypress.com, netdev@vger.kernel.org, =?UTF-8?q?Linus=20L=C3=BCssing?= , Felix Fietkau , bridge@lists.linux-foundation.org, =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Subject: [PATCH V2] brcmfmac: drop Inter-Access Point Protocol packets by default Date: Thu, 15 Mar 2018 08:29:09 +0100 Message-Id: <20180315072909.1512-1-zajec5@gmail.com> X-Mailer: git-send-email 2.11.0 MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Rafał Miłecki Testing brcmfmac with more recent firmwares resulted in AP interfaces not working in some specific setups. Debugging resulted in discovering support for IAPP in Broadcom's firmwares. Older firmwares were only generating 802.11f frames. Newer ones like: 1) 10.10 (TOB) (r663589) 2) 10.10.122.20 (r683106) for 4366b1 and 4366c0 respectively seem to also /respect/ 802.11f frames in the Tx path by performing a STA disassociation. This obsoleted standard and its implementation is something that: 1) Most people don't need / want to use 2) Can allow local DoS attacks 3) Breaks AP interfaces in some specific bridge setups To solve issues it can cause this commit modifies brcmfmac to drop IAPP packets. If affects: 1) Rx path: driver won't be sending these unwanted packets up. 2) Tx path: driver will reject packets that would trigger STA disassociation perfromed by a firmware (possible local DoS attack). It appears there are some Broadcom's clients/users who care about this feature despite the drawbacks. They can switch it on using a new module param. This change results in only two more comparisons (check for module param and check for Ethernet packet length) for 99.9% of packets. Its overhead should be very minimal. Signed-off-by: Rafał Miłecki Acked-by: Arend van Spriel --- .../wireless/broadcom/brcm80211/brcmfmac/common.c | 5 ++ .../wireless/broadcom/brcm80211/brcmfmac/common.h | 1 + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 57 ++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 70ef9835b647..5532ef39439f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -75,6 +75,10 @@ static int brcmf_roamoff; module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR); MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); +static int brcmf_iapp_enable; +module_param_named(iapp, brcmf_iapp_enable, int, 0); +MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol"); + #ifdef DEBUG /* always succeed brcmf_bus_started() */ static int brcmf_ignore_probe_fail; @@ -438,6 +442,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, settings->feature_disable = brcmf_feature_disable; settings->fcmode = brcmf_fcmode; settings->roamoff = !!brcmf_roamoff; + settings->iapp = !!brcmf_iapp_enable; #ifdef DEBUG settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; #endif diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h index a62f8e70b320..ef914619e8e1 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h @@ -58,6 +58,7 @@ struct brcmf_mp_device { unsigned int feature_disable; int fcmode; bool roamoff; + bool iapp; bool ignore_probe_fail; struct brcmfmac_pd_cc *country_codes; union { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 19048526b4af..ca97a8b4c59f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -230,6 +230,37 @@ static void brcmf_netdev_set_multicast_list(struct net_device *ndev) schedule_work(&ifp->multicast_work); } +/** + * brcmf_skb_is_iapp - checks if skb is an IAPP packet + * + * @skb: skb to check + */ +static bool brcmf_skb_is_iapp(struct sk_buff *skb) +{ + static const u8 iapp_l2_update_packet[6] __aligned(2) = { + 0x00, 0x01, 0xaf, 0x81, 0x01, 0x00, + }; + unsigned char *eth_data; +#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) + const u16 *a, *b; +#endif + + if (skb->len - skb->mac_len != 6 || + !is_multicast_ether_addr(eth_hdr(skb)->h_dest)) + return false; + + eth_data = skb_mac_header(skb) + ETH_HLEN; +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) + return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) | + ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4)))); +#else + a = (const u16 *)eth_data; + b = (const u16 *)iapp_l2_update_packet; + + return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])); +#endif +} + static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) { @@ -250,6 +281,23 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, goto done; } + /* Some recent Broadcom's firmwares disassociate STA when they receive + * an 802.11f ADD frame. This behavior can lead to a local DoS security + * issue. Attacker may trigger disassociation of any STA by sending a + * proper Ethernet frame to the wireless interface. + * + * Moreover this feature may break AP interfaces in some specific + * setups. This applies e.g. to the bridge with hairpin mode enabled and + * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware + * will get passed back to the wireless interface and cause immediate + * disassociation of a just-connected STA. + */ + if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) { + dev_kfree_skb(skb); + ret = -EINVAL; + goto done; + } + /* Make sure there's enough writeable headroom */ if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) { head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0); @@ -325,6 +373,15 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp, void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) { + /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new + * STA connects to the AP interface. This is an obsoleted standard most + * users don't use, so don't pass these frames up unless requested. + */ + if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) { + brcmu_pkt_buf_free_skb(skb); + return; + } + if (skb->pkt_type == PACKET_MULTICAST) ifp->ndev->stats.multicast++;