lkml.org 
[lkml]   [2021]   [May]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 014/177] mac80211: assure all fragments are encrypted
    Date
    From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>

    commit 965a7d72e798eb7af0aa67210e37cf7ecd1c9cad upstream.

    Do not mix plaintext and encrypted fragments in protected Wi-Fi
    networks. This fixes CVE-2020-26147.

    Previously, an attacker was able to first forward a legitimate encrypted
    fragment towards a victim, followed by a plaintext fragment. The
    encrypted and plaintext fragment would then be reassembled. For further
    details see Section 6.3 and Appendix D in the paper "Fragment and Forge:
    Breaking Wi-Fi Through Frame Aggregation and Fragmentation".

    Because of this change there are now two equivalent conditions in the
    code to determine if a received fragment requires sequential PNs, so we
    also move this test to a separate function to make the code easier to
    maintain.

    Cc: stable@vger.kernel.org
    Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
    Link: https://lore.kernel.org/r/20210511200110.30c4394bb835.I5acfdb552cc1d20c339c262315950b3eac491397@changeid
    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/mac80211/rx.c | 23 ++++++++++++-----------
    1 file changed, 12 insertions(+), 11 deletions(-)

    --- a/net/mac80211/rx.c
    +++ b/net/mac80211/rx.c
    @@ -2154,6 +2154,16 @@ ieee80211_reassemble_find(struct ieee802
    return NULL;
    }

    +static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc)
    +{
    + return rx->key &&
    + (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
    + rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 ||
    + rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP ||
    + rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) &&
    + ieee80211_has_protected(fc);
    +}
    +
    static ieee80211_rx_result debug_noinline
    ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
    {
    @@ -2198,12 +2208,7 @@ ieee80211_rx_h_defragment(struct ieee802
    /* This is the first fragment of a new frame. */
    entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
    rx->seqno_idx, &(rx->skb));
    - if (rx->key &&
    - (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
    - rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 ||
    - rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP ||
    - rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) &&
    - ieee80211_has_protected(fc)) {
    + if (requires_sequential_pn(rx, fc)) {
    int queue = rx->security_idx;

    /* Store CCMP/GCMP PN so that we can verify that the
    @@ -2245,11 +2250,7 @@ ieee80211_rx_h_defragment(struct ieee802
    u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
    int queue;

    - if (!rx->key ||
    - (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP &&
    - rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 &&
    - rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP &&
    - rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256))
    + if (!requires_sequential_pn(rx, fc))
    return RX_DROP_UNUSABLE;
    memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
    for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {

    \
     
     \ /
      Last update: 2021-05-31 17:34    [W:4.161 / U:0.100 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site