]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
mac80211: do not accept/forward invalid EAPOL frames
authorJohannes Berg <johannes.berg@intel.com>
Tue, 25 May 2021 17:46:00 +0000 (19:46 +0200)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Fri, 28 May 2021 10:39:09 +0000 (12:39 +0200)
EAPOL frames are used for authentication and key management between the
AP and each individual STA associated in the BSS. Those frames are not
supposed to be sent by one associated STA to another associated STA
(either unicast for broadcast/multicast).

Similarly, in 802.11 they're supposed to be sent to the authenticator
(AP) address.

Since it is possible for unexpected EAPOL frames to result in misbehavior
in supplicant implementations, it is better for the AP to not allow such
cases to be forwarded to other clients either directly, or indirectly if
the AP interface is part of a bridge.

Accept EAPOL (control port) frames only if they're transmitted to the
own address, or, due to interoperability concerns, to the PAE group
address.

Disable forwarding of EAPOL (or well, the configured control port
protocol) frames back to wireless medium in all cases. Previously, these
frames were accepted from fully authenticated and authorized stations
and also from unauthenticated stations for one of the cases.

Additionally, to avoid forwarding by the bridge, rewrite the PAE group
address case to the local MAC address.

Cc: stable@vger.kernel.org
Co-developed-by: Jouni Malinen <jouni@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Link: https://lore.kernel.org/r/20210511200110.cb327ed0cabe.Ib7dcffa2a31f0913d660de65ba3c8aca75b1d10f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
(cherry picked from commit a8c4d76a8dd4fb9666fc8919a703d85fb8f44ed8)
CVE-2020-26139
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Acked-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
net/mac80211/rx.c

index 49fada44d6a481548866990fb2deeedaf07f229f..f43ebeaf9181845b8af6ddc6c6c307346070d0a4 100644 (file)
@@ -2539,13 +2539,13 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc)
        struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
 
        /*
-        * Allow EAPOL frames to us/the PAE group address regardless
-        * of whether the frame was encrypted or not.
+        * Allow EAPOL frames to us/the PAE group address regardless of
+        * whether the frame was encrypted or not, and always disallow
+        * all other destination addresses for them.
         */
-       if (ehdr->h_proto == rx->sdata->control_port_protocol &&
-           (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) ||
-            ether_addr_equal(ehdr->h_dest, pae_group_addr)))
-               return true;
+       if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol))
+               return ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) ||
+                      ether_addr_equal(ehdr->h_dest, pae_group_addr);
 
        if (ieee80211_802_1x_port_control(rx) ||
            ieee80211_drop_unencrypted(rx, fc))
@@ -2570,8 +2570,28 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
                cfg80211_rx_control_port(dev, skb, noencrypt);
                dev_kfree_skb(skb);
        } else {
+               struct ethhdr *ehdr = (void *)skb_mac_header(skb);
+
                memset(skb->cb, 0, sizeof(skb->cb));
 
+               /*
+                * 802.1X over 802.11 requires that the authenticator address
+                * be used for EAPOL frames. However, 802.1X allows the use of
+                * the PAE group address instead. If the interface is part of
+                * a bridge and we pass the frame with the PAE group address,
+                * then the bridge will forward it to the network (even if the
+                * client was not associated yet), which isn't supposed to
+                * happen.
+                * To avoid that, rewrite the destination address to our own
+                * address, so that the authenticator (e.g. hostapd) will see
+                * the frame, but bridge won't forward it anywhere else. Note
+                * that due to earlier filtering, the only other address can
+                * be the PAE group address.
+                */
+               if (unlikely(skb->protocol == sdata->control_port_protocol &&
+                            !ether_addr_equal(ehdr->h_dest, sdata->vif.addr)))
+                       ether_addr_copy(ehdr->h_dest, sdata->vif.addr);
+
                /* deliver to local stack */
                if (rx->list)
                        list_add_tail(&skb->list, rx->list);
@@ -2611,6 +2631,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
        if ((sdata->vif.type == NL80211_IFTYPE_AP ||
             sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
            !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
+           ehdr->h_proto != rx->sdata->control_port_protocol &&
            (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) {
                if (is_multicast_ether_addr(ehdr->h_dest) &&
                    ieee80211_vif_get_num_mcast_if(sdata) != 0) {