.. | .. |
---|
2146 | 2146 | goto exit; |
---|
2147 | 2147 | } |
---|
2148 | 2148 | |
---|
2149 | | - if ((psta->flags & WLAN_STA_AMSDU_DISABLE) && pattrib->amsdu) { |
---|
2150 | | - #ifdef DBG_RX_DROP_FRAME |
---|
2151 | | - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" amsdu not allowed"MAC_FMT"\n" |
---|
2152 | | - , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); |
---|
2153 | | - #endif |
---|
2154 | | - ret = _FAIL; |
---|
2155 | | - goto exit; |
---|
2156 | | - |
---|
2157 | | - } |
---|
2158 | | - |
---|
2159 | | - |
---|
2160 | 2149 | precv_frame->u.hdr.psta = psta; |
---|
2161 | 2150 | precv_frame->u.hdr.preorder_ctrl = NULL; |
---|
2162 | 2151 | pattrib->ack_policy = 0; |
---|
.. | .. |
---|
2204 | 2193 | #endif |
---|
2205 | 2194 | ret = _FAIL; |
---|
2206 | 2195 | goto exit; |
---|
2207 | | - } |
---|
2208 | | - } |
---|
2209 | | - |
---|
2210 | | - if (pattrib->privacy) { |
---|
2211 | | -#ifdef CONFIG_TDLS |
---|
2212 | | - if ((psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta->dot118021XPrivacy == _AES_)) |
---|
2213 | | - pattrib->encrypt = psta->dot118021XPrivacy; |
---|
2214 | | - else |
---|
2215 | | -#endif /* CONFIG_TDLS */ |
---|
2216 | | - GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra)); |
---|
2217 | | - |
---|
2218 | | - |
---|
2219 | | - SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); |
---|
2220 | | - } else { |
---|
2221 | | - pattrib->encrypt = 0; |
---|
2222 | | - pattrib->iv_len = pattrib->icv_len = 0; |
---|
2223 | | - } |
---|
2224 | | - |
---|
2225 | | - /* drop unprotected frame in protected network. */ |
---|
2226 | | - if (psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ ) { |
---|
2227 | | - if (IS_MCAST(pattrib->ra)) { |
---|
2228 | | - if (!pattrib->privacy) { |
---|
2229 | | - #ifdef DBG_RX_DROP_FRAME |
---|
2230 | | - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT"recv plaintext bmc packet for sta="MAC_FMT"\n" |
---|
2231 | | - , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); |
---|
2232 | | - #endif |
---|
2233 | | - ret = _FAIL; |
---|
2234 | | - goto exit; |
---|
2235 | | - } |
---|
2236 | | - } else { |
---|
2237 | | - /* unicast */ |
---|
2238 | | - u16 ether_type; |
---|
2239 | | - u8* ether_ptr = NULL; |
---|
2240 | | - u16 eapol_type = 0x888e; |
---|
2241 | | - ether_ptr = ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + LLC_HEADER_SIZE; |
---|
2242 | | - _rtw_memcpy(ðer_type, ether_ptr, 2); |
---|
2243 | | - ether_type = ntohs((unsigned short)ether_type); |
---|
2244 | | - |
---|
2245 | | - if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { |
---|
2246 | | - /* CVE-2020-26140, CVE-2020-26143, CVE-2020-26147, let eapol packet go through*/ |
---|
2247 | | - if (!pattrib->privacy && ether_type != eapol_type ) { |
---|
2248 | | - #ifdef DBG_RX_DROP_FRAME |
---|
2249 | | - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT"recv plaintext unicast packet for sta="MAC_FMT"\n" |
---|
2250 | | - , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); |
---|
2251 | | - #endif |
---|
2252 | | - ret = _FAIL; |
---|
2253 | | - goto exit; |
---|
2254 | | - } |
---|
2255 | | - /* CVE-2020-26144, pevernt plaintext A-MSDU */ |
---|
2256 | | - /* This can prevent plantext A-MSDU cloacked as an EAPOL frame */ |
---|
2257 | | - if (!pattrib->privacy && pattrib->amsdu) { |
---|
2258 | | - #ifdef DBG_RX_DROP_FRAME |
---|
2259 | | - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT"recv plaintext A-MSDU for sta="MAC_FMT"\n" |
---|
2260 | | - , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); |
---|
2261 | | - #endif |
---|
2262 | | - ret = _FAIL; |
---|
2263 | | - goto exit; |
---|
2264 | | - } |
---|
2265 | | - /* CVE-2020-26139, Drop any forwarding eapol packet until 4-way has done. */ |
---|
2266 | | - if ((ether_type == eapol_type) |
---|
2267 | | - && (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) |
---|
2268 | | - && (psta->dot118021XPrivacy == _NO_PRIVACY_) |
---|
2269 | | - && (!_rtw_memcmp( adapter_mac_addr(adapter), pattrib->dst, ETH_ALEN))) { |
---|
2270 | | - #ifdef DBG_RX_DROP_FRAME |
---|
2271 | | - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recv eapol packet forwarding(dst:"MAC_FMT") before 4-way finish.\n" |
---|
2272 | | - , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->dst)); |
---|
2273 | | - #endif |
---|
2274 | | - ret = _FAIL; |
---|
2275 | | - goto exit; |
---|
2276 | | - } |
---|
2277 | | - } else { |
---|
2278 | | - /* CVE-2020-26140, CVE-2020-26143, CVE-2020-26147 */ |
---|
2279 | | - if (!pattrib->privacy) { |
---|
2280 | | - #ifdef DBG_RX_DROP_FRAME |
---|
2281 | | - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT"recv plaintext packet for sta="MAC_FMT"\n" |
---|
2282 | | - , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr)); |
---|
2283 | | - #endif |
---|
2284 | | - ret = _FAIL; |
---|
2285 | | - goto exit; |
---|
2286 | | - } |
---|
2287 | | - } |
---|
2288 | 2196 | } |
---|
2289 | 2197 | } |
---|
2290 | 2198 | |
---|
.. | .. |
---|
2640 | 2548 | union recv_frame *prframe, *pnextrframe; |
---|
2641 | 2549 | _queue *pfree_recv_queue; |
---|
2642 | 2550 | |
---|
2643 | | - u8 *pdata = NULL; |
---|
2644 | | - u64 tmp_iv_hdr = 0; |
---|
2645 | | - u64 pkt_pn = 0, cur_pn = 0; |
---|
2646 | | - struct rx_pkt_attrib *pattrib = NULL; |
---|
2647 | 2551 | |
---|
2648 | 2552 | curfragnum = 0; |
---|
2649 | 2553 | pfree_recv_queue = &adapter->recvpriv.free_recv_queue; |
---|
.. | .. |
---|
2651 | 2555 | phead = get_list_head(defrag_q); |
---|
2652 | 2556 | plist = get_next(phead); |
---|
2653 | 2557 | prframe = LIST_CONTAINOR(plist, union recv_frame, u); |
---|
2654 | | - /* CVE-2020-26146 */ |
---|
2655 | | - pattrib = &prframe->u.hdr.attrib; |
---|
2656 | | - if (pattrib->encrypt == _AES_ || pattrib->encrypt == _CCMP_256_ |
---|
2657 | | - || pattrib->encrypt == _GCMP_ || pattrib->encrypt == _GCMP_256_ ) { |
---|
2658 | | - pdata = prframe->u.hdr.rx_data; |
---|
2659 | | - tmp_iv_hdr = le64_to_cpu(*(u64*)(pdata + pattrib->hdrlen)); |
---|
2660 | | - /* get the first frame's PN. */ |
---|
2661 | | - cur_pn = CCMPH_2_PN(tmp_iv_hdr); |
---|
2662 | | - } |
---|
2663 | 2558 | pfhdr = &prframe->u.hdr; |
---|
2664 | 2559 | rtw_list_delete(&(prframe->u.list)); |
---|
2665 | 2560 | |
---|
.. | .. |
---|
2689 | 2584 | while (rtw_end_of_queue_search(phead, plist) == _FALSE) { |
---|
2690 | 2585 | pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u); |
---|
2691 | 2586 | pnfhdr = &pnextrframe->u.hdr; |
---|
2692 | | - /* CVE-2020-26146, check whether the PN is consecutive. */ |
---|
2693 | | - pattrib = &pnextrframe->u.hdr.attrib; |
---|
2694 | | - if (pattrib->encrypt == _AES_ || pattrib->encrypt == _CCMP_256_ |
---|
2695 | | - || pattrib->encrypt == _GCMP_ || pattrib->encrypt == _GCMP_256_ ) { |
---|
2696 | | - pdata = pnextrframe->u.hdr.rx_data; |
---|
2697 | | - tmp_iv_hdr = le64_to_cpu(*(u64*)(pdata + pattrib->hdrlen)); |
---|
2698 | | - pkt_pn = CCMPH_2_PN(tmp_iv_hdr); |
---|
2699 | | - if (pkt_pn != cur_pn + 1) { |
---|
2700 | | - RTW_INFO("%s non-consective PN! old:%llu, new:%llu\n", |
---|
2701 | | - __func__, cur_pn, pkt_pn); |
---|
2702 | | - /* PN must be consecutive */ |
---|
2703 | | - /* release the defrag_q & prframe */ |
---|
2704 | | - rtw_free_recvframe(prframe, pfree_recv_queue); |
---|
2705 | | - rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); |
---|
2706 | | - return NULL; |
---|
2707 | | - } else { |
---|
2708 | | - cur_pn = pkt_pn; |
---|
2709 | | - } |
---|
2710 | | - } |
---|
2711 | | - |
---|
2712 | | - /* CVE-2020-24587, The keytrack of the fragment is supposed to be the same with other's */ |
---|
2713 | | - if (pfhdr->keytrack != pnfhdr->keytrack) { |
---|
2714 | | - RTW_INFO("Inconsistent key track, drop fragmented frame!\n"); |
---|
2715 | | - rtw_free_recvframe(prframe, pfree_recv_queue); |
---|
2716 | | - rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); |
---|
2717 | | - return NULL; |
---|
2718 | | - } |
---|
2719 | 2587 | |
---|
2720 | 2588 | |
---|
2721 | 2589 | /* check the fragment sequence (2nd ~n fragment frame) */ |
---|
.. | .. |
---|
2728 | 2596 | return NULL; |
---|
2729 | 2597 | } |
---|
2730 | 2598 | |
---|
| 2599 | + curfragnum++; |
---|
| 2600 | + |
---|
2731 | 2601 | /* copy the 2nd~n fragment frame's payload to the first fragment */ |
---|
2732 | 2602 | /* get the 2nd~last fragment frame's payload */ |
---|
2733 | 2603 | |
---|
2734 | 2604 | wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; |
---|
2735 | 2605 | |
---|
2736 | 2606 | recvframe_pull(pnextrframe, wlanhdr_offset); |
---|
2737 | | - |
---|
2738 | | - if ((pfhdr->rx_end - pfhdr->rx_tail) < pnfhdr->len) { |
---|
2739 | | - RTW_INFO("Not enough buffer space, drop fragmented frame!\n"); |
---|
2740 | | - rtw_free_recvframe(prframe, pfree_recv_queue); |
---|
2741 | | - rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); |
---|
2742 | | - return NULL; |
---|
2743 | | - } |
---|
2744 | | - |
---|
2745 | | - curfragnum++; |
---|
2746 | 2607 | |
---|
2747 | 2608 | /* append to first fragment frame's tail (if privacy frame, pull the ICV) */ |
---|
2748 | 2609 | recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); |
---|
.. | .. |
---|
2804 | 2665 | |
---|
2805 | 2666 | if ((ismfrag == 0) && (fragnum == 0)) { |
---|
2806 | 2667 | prtnframe = precv_frame;/* isn't a fragment frame */ |
---|
2807 | | - } else { |
---|
2808 | | - /* CVE-2020-26145, group addressed frame cannot use fragmentation!! */ |
---|
2809 | | - if (IS_MCAST(pfhdr->attrib.ra)) { |
---|
2810 | | - RTW_INFO("DROP group addressed fragment!\n"); |
---|
2811 | | - rtw_free_recvframe(precv_frame, pfree_recv_queue); |
---|
2812 | | - return NULL; |
---|
2813 | | - } |
---|
2814 | | - /* CVE-2020-24587 */ |
---|
2815 | | - if ((psta) && (pdefrag_q)) |
---|
2816 | | - precv_frame->u.hdr.keytrack = ATOMIC_READ(&psta->keytrack); |
---|
2817 | | - |
---|
2818 | 2668 | } |
---|
2819 | 2669 | |
---|
2820 | 2670 | if (ismfrag == 1) { |
---|
.. | .. |
---|
3052 | 2902 | } |
---|
3053 | 2903 | #endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) */ |
---|
3054 | 2904 | |
---|
3055 | | -/* |
---|
3056 | | - * From WFA suggestion: * |
---|
3057 | | - * If first subframe meets one of the following condition, * |
---|
3058 | | - * the whole received AMSDU should drop. * |
---|
3059 | | - * 1. subframe's DA is not the same as RA in From DS case. * |
---|
3060 | | - * 2. subframe's SA is not the same as TA in To DS case. * |
---|
3061 | | - * 3. subframe's DA is AA:AA:03:00:00:00 * |
---|
3062 | | - */ |
---|
3063 | | -static u8 validate_amsdu_content(_adapter *padapter, union recv_frame *prframe, |
---|
3064 | | - const u8 *da, const u8 *sa) |
---|
3065 | | -{ |
---|
3066 | | - struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; |
---|
3067 | | - u8 ret = _SUCCESS; |
---|
3068 | | - |
---|
3069 | | - /* Use the recommendation method form Wi-Fi alliance to check subframe */ |
---|
3070 | | - /* in protected network */ |
---|
3071 | | - if (padapter->registrypriv.amsdu_mode == RTW_AMSDU_MODE_NON_SPP && |
---|
3072 | | - padapter->securitypriv.dot11PrivacyAlgrthm != _NO_PRIVACY_) { |
---|
3073 | | - |
---|
3074 | | - /* 1.check From DS */ |
---|
3075 | | - if (pattrib->to_fr_ds == 2) { |
---|
3076 | | - if (_rtw_memcmp(da, pattrib->ra, ETH_ALEN) == _FALSE) |
---|
3077 | | - ret = _FAIL; |
---|
3078 | | - } |
---|
3079 | | - |
---|
3080 | | - /* 2.check To DS */ |
---|
3081 | | - if (pattrib->to_fr_ds == 1) { |
---|
3082 | | - if (_rtw_memcmp(sa, pattrib->ta, ETH_ALEN) == _FALSE) |
---|
3083 | | - ret = _FAIL; |
---|
3084 | | - } |
---|
3085 | | - |
---|
3086 | | - /* 3.Check whether DA is AA:AA:03:00:00:00 */ |
---|
3087 | | - if (_rtw_memcmp(da, rtw_rfc1042_header, ETH_ALEN) == _TRUE) |
---|
3088 | | - ret = _FAIL; |
---|
3089 | | - |
---|
3090 | | - } |
---|
3091 | | - |
---|
3092 | | - return ret; |
---|
3093 | | - |
---|
3094 | | -} |
---|
3095 | | - |
---|
3096 | 2905 | int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) |
---|
3097 | 2906 | { |
---|
3098 | 2907 | struct rx_pkt_attrib *rattrib = &prframe->u.hdr.attrib; |
---|
.. | .. |
---|
3146 | 2955 | |
---|
3147 | 2956 | v_ret = rtw_mesh_rx_data_validate_mctrl(padapter, prframe |
---|
3148 | 2957 | , mctrl, mda, msa, &mctrl_len, &da, &sa); |
---|
3149 | | - |
---|
3150 | | - if (validate_amsdu_content(padapter, prframe, da, sa) == _FAIL) { |
---|
3151 | | - RTW_INFO("%s check subframe content fail!\n", __func__); |
---|
3152 | | - break; |
---|
3153 | | - } |
---|
3154 | | - |
---|
3155 | 2958 | if (v_ret != _SUCCESS) |
---|
3156 | 2959 | goto move_to_next; |
---|
3157 | 2960 | |
---|
.. | .. |
---|
3165 | 2968 | { |
---|
3166 | 2969 | da = pdata; |
---|
3167 | 2970 | sa = pdata + ETH_ALEN; |
---|
3168 | | - |
---|
3169 | | - if (validate_amsdu_content(padapter, prframe, da, sa) == _FAIL) { |
---|
3170 | | - RTW_INFO("%s check subframe content fail!\n", __func__); |
---|
3171 | | - break; |
---|
3172 | | - } |
---|
3173 | | - |
---|
3174 | 2971 | llc_hdl = rtw_recv_llc_parse(pdata + ETH_HLEN, nSubframe_Length); |
---|
3175 | 2972 | #ifdef CONFIG_AP_MODE |
---|
3176 | 2973 | if (MLME_IS_AP(padapter)) { |
---|
.. | .. |
---|
4867 | 4664 | s32 err = _SUCCESS; |
---|
4868 | 4665 | #ifdef RTW_RECV_THREAD_HIGH_PRIORITY |
---|
4869 | 4666 | #ifdef PLATFORM_LINUX |
---|
4870 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) |
---|
4871 | | - sched_set_fifo_low(current); |
---|
4872 | | -#else |
---|
4873 | 4667 | struct sched_param param = { .sched_priority = 1 }; |
---|
4874 | | - |
---|
| 4668 | + |
---|
4875 | 4669 | sched_setscheduler(current, SCHED_FIFO, ¶m); |
---|
4876 | | -#endif |
---|
4877 | 4670 | #endif /* PLATFORM_LINUX */ |
---|
4878 | 4671 | #endif /*RTW_RECV_THREAD_HIGH_PRIORITY*/ |
---|
4879 | 4672 | thread_enter("RTW_RECV_THREAD"); |
---|