lkml.org 
[lkml]   [2018]   [May]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 082/496] iwlwifi: mvm: fix security bug in PN checking
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Sara Sharon <sara.sharon@intel.com>

    [ Upstream commit 5ab2ba931255d8bf03009c06d58dce97de32797c ]

    A previous patch allowed the same PN for packets originating from the
    same AMSDU by copying PN only for the last packet in the series.

    This however is bogus since we cannot assume the last frame will be
    received on the same queue, and if it is received on a different ueue
    we will end up not incrementing the PN and possibly let the next
    packet to have the same PN and pass through.

    Change the logic instead to driver explicitly indicate for the second
    sub frame and on to be allowed to have the same PN as the first
    subframe. Indicate it to mac80211 as well for the fallback queue.

    Fixes: f1ae02b186d9 ("iwlwifi: mvm: allow same PN for de-aggregated AMSDU")
    Signed-off-by: Sara Sharon <sara.sharon@intel.com>
    Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 39 +++++++++++++-------------
    1 file changed, 20 insertions(+), 19 deletions(-)

    --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
    +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
    @@ -71,6 +71,7 @@ static inline int iwl_mvm_check_pn(struc
    struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
    struct ieee80211_rx_status *stats = IEEE80211_SKB_RXCB(skb);
    struct iwl_mvm_key_pn *ptk_pn;
    + int res;
    u8 tid, keyidx;
    u8 pn[IEEE80211_CCMP_PN_LEN];
    u8 *extiv;
    @@ -127,12 +128,13 @@ static inline int iwl_mvm_check_pn(struc
    pn[4] = extiv[1];
    pn[5] = extiv[0];

    - if (memcmp(pn, ptk_pn->q[queue].pn[tid],
    - IEEE80211_CCMP_PN_LEN) <= 0)
    + res = memcmp(pn, ptk_pn->q[queue].pn[tid], IEEE80211_CCMP_PN_LEN);
    + if (res < 0)
    + return -1;
    + if (!res && !(stats->flag & RX_FLAG_ALLOW_SAME_PN))
    return -1;

    - if (!(stats->flag & RX_FLAG_AMSDU_MORE))
    - memcpy(ptk_pn->q[queue].pn[tid], pn, IEEE80211_CCMP_PN_LEN);
    + memcpy(ptk_pn->q[queue].pn[tid], pn, IEEE80211_CCMP_PN_LEN);
    stats->flag |= RX_FLAG_PN_VALIDATED;

    return 0;
    @@ -310,28 +312,21 @@ static void iwl_mvm_rx_csum(struct ieee8
    }

    /*
    - * returns true if a packet outside BA session is a duplicate and
    - * should be dropped
    + * returns true if a packet is a duplicate and should be dropped.
    + * Updates AMSDU PN tracking info
    */
    -static bool iwl_mvm_is_nonagg_dup(struct ieee80211_sta *sta, int queue,
    - struct ieee80211_rx_status *rx_status,
    - struct ieee80211_hdr *hdr,
    - struct iwl_rx_mpdu_desc *desc)
    +static bool iwl_mvm_is_dup(struct ieee80211_sta *sta, int queue,
    + struct ieee80211_rx_status *rx_status,
    + struct ieee80211_hdr *hdr,
    + struct iwl_rx_mpdu_desc *desc)
    {
    struct iwl_mvm_sta *mvm_sta;
    struct iwl_mvm_rxq_dup_data *dup_data;
    - u8 baid, tid, sub_frame_idx;
    + u8 tid, sub_frame_idx;

    if (WARN_ON(IS_ERR_OR_NULL(sta)))
    return false;

    - baid = (le32_to_cpu(desc->reorder_data) &
    - IWL_RX_MPDU_REORDER_BAID_MASK) >>
    - IWL_RX_MPDU_REORDER_BAID_SHIFT;
    -
    - if (baid != IWL_RX_REORDER_DATA_INVALID_BAID)
    - return false;
    -
    mvm_sta = iwl_mvm_sta_from_mac80211(sta);
    dup_data = &mvm_sta->dup_data[queue];

    @@ -361,6 +356,12 @@ static bool iwl_mvm_is_nonagg_dup(struct
    dup_data->last_sub_frame[tid] >= sub_frame_idx))
    return true;

    + /* Allow same PN as the first subframe for following sub frames */
    + if (dup_data->last_seq[tid] == hdr->seq_ctrl &&
    + sub_frame_idx > dup_data->last_sub_frame[tid] &&
    + desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU)
    + rx_status->flag |= RX_FLAG_ALLOW_SAME_PN;
    +
    dup_data->last_seq[tid] = hdr->seq_ctrl;
    dup_data->last_sub_frame[tid] = sub_frame_idx;

    @@ -929,7 +930,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *
    if (ieee80211_is_data(hdr->frame_control))
    iwl_mvm_rx_csum(sta, skb, desc);

    - if (iwl_mvm_is_nonagg_dup(sta, queue, rx_status, hdr, desc)) {
    + if (iwl_mvm_is_dup(sta, queue, rx_status, hdr, desc)) {
    kfree_skb(skb);
    goto out;
    }

    \
     
     \ /
      Last update: 2018-05-28 12:45    [W:4.049 / U:0.604 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site