qcacmn: Add check for frame boundary check in t2lm api

While parsing t2lm ie pass the frame length and add
check for frame boundary.

Change-Id: Iebb2cb5f0756785e4698613b80bfb31d60a2ed80
CRs-Fixed: 3577156
This commit is contained in:
Amruta Kulkarni
2023-08-02 13:41:37 -07:00
committad av Rahul Choudhary
förälder bb3b798604
incheckning 712aff4786
2 ändrade filer med 34 tillägg och 9 borttagningar

Visa fil

@@ -552,11 +552,13 @@ QDF_STATUS wlan_mlo_dev_t2lm_notify_link_update(
* wlan_mlo_parse_t2lm_ie() - API to parse the T2LM IE
* @t2lm: Pointer to T2LM structure
* @ie: Pointer to T2LM IE
* @frame_len: Action Frame length
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_mlo_parse_t2lm_ie(
struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie);
struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie,
uint32_t frame_len);
/**
* wlan_mlo_add_t2lm_ie() - API to add TID-to-link mapping IE
@@ -586,6 +588,7 @@ QDF_STATUS wlan_mlo_vdev_tid_to_link_map_event(
* wlan_mlo_parse_t2lm_action_frame() - API to parse T2LM action frame
* @t2lm: Pointer to T2LM structure
* @action_frm: Pointer to action frame
* @frame_len: Action frame length
* @category: T2LM action frame category
*
* Return: 0 - success, else failure
@@ -593,6 +596,7 @@ QDF_STATUS wlan_mlo_vdev_tid_to_link_map_event(
int wlan_mlo_parse_t2lm_action_frame(
struct wlan_t2lm_onging_negotiation_info *t2lm,
struct wlan_action_frame *action_frm,
uint32_t frame_len,
enum wlan_t2lm_category category);
/**
@@ -745,7 +749,8 @@ wlan_send_peer_level_tid_to_link_mapping(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer);
#else
static inline QDF_STATUS wlan_mlo_parse_t2lm_ie(
struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie)
struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie,
uint32_t frame_len)
{
return QDF_STATUS_E_FAILURE;
}
@@ -762,6 +767,7 @@ static inline
int wlan_mlo_parse_t2lm_action_frame(
struct wlan_t2lm_onging_negotiation_info *t2lm,
struct wlan_action_frame *action_frm,
uint32_t frame_len,
enum wlan_t2lm_category category)
{
return 0;

Visa fil

@@ -188,26 +188,38 @@ QDF_STATUS wlan_mlo_parse_bcn_prbresp_t2lm_ie(
}
QDF_STATUS wlan_mlo_parse_t2lm_ie(
struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie)
struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie,
uint32_t frame_len)
{
struct extn_ie_header *ext_ie_hdr = NULL;
QDF_STATUS retval;
enum wlan_t2lm_direction dir;
struct wlan_t2lm_info t2lm_info;
uint32_t ie_len_parsed = 0;
for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++)
t2lm->t2lm_info[dir].direction = WLAN_T2LM_INVALID_DIRECTION;
for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++) {
if (!ie) {
t2lm_err("ie is null");
if (!ie || !frame_len) {
t2lm_err("ie is null or len is 0");
return QDF_STATUS_E_NULL_VALUE;
}
if (frame_len < (ie_len_parsed + sizeof(struct ie_header))) {
t2lm_err("Frame length is lesser than parsed T2LM IE header length");
return QDF_STATUS_E_PROTO;
}
ext_ie_hdr = (struct extn_ie_header *)ie;
if (ext_ie_hdr->ie_id == WLAN_ELEMID_EXTN_ELEM &&
ext_ie_hdr->ie_extn_id == WLAN_EXTN_ELEMID_T2LM) {
ie_len_parsed += ext_ie_hdr->ie_len + sizeof(struct ie_header);
if (frame_len < ie_len_parsed) {
t2lm_err("Frame length is lesser than parsed T2LM IE length");
return QDF_STATUS_E_PROTO;
}
qdf_mem_zero(&t2lm_info, sizeof(t2lm_info));
retval = wlan_mlo_parse_t2lm_info(ie, &t2lm_info);
if (!retval &&
@@ -425,6 +437,7 @@ uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm,
* frame.
* @t2lm: Pointer to T2LM structure
* @action_frm: Pointer to action frame
* @frame_len: Received frame pointer
* @category: T2LM action frame category
*
* Return: QDF_STATUS
@@ -432,6 +445,7 @@ uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm,
static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame(
struct wlan_t2lm_onging_negotiation_info *t2lm,
struct wlan_action_frame *action_frm,
uint32_t frame_len,
enum wlan_t2lm_category category)
{
uint8_t *t2lm_action_frm;
@@ -455,7 +469,8 @@ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame(
t2lm->dialog_token = *t2lm_action_frm;
return wlan_mlo_parse_t2lm_ie(t2lm,
t2lm_action_frm + sizeof(uint8_t));
t2lm_action_frm + sizeof(uint8_t),
frame_len);
}
/**
@@ -463,6 +478,7 @@ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame(
* action frame.
* @t2lm: Pointer to T2LM structure
* @action_frm: Pointer to action frame
* @frame_len: Action frame length
* @category: T2LM action frame category
*
* Return: QDF_STATUS
@@ -470,6 +486,7 @@ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame(
static QDF_STATUS wlan_mlo_parse_t2lm_response_action_frame(
struct wlan_t2lm_onging_negotiation_info *t2lm,
struct wlan_action_frame *action_frm,
uint32_t frame_len,
enum wlan_t2lm_category category)
{
uint8_t *t2lm_action_frm;
@@ -497,7 +514,8 @@ static QDF_STATUS wlan_mlo_parse_t2lm_response_action_frame(
if (t2lm->t2lm_resp_type ==
WLAN_T2LM_RESP_TYPE_PREFERRED_TID_TO_LINK_MAPPING) {
t2lm_action_frm += sizeof(uint8_t) + sizeof(uint16_t);
ret_val = wlan_mlo_parse_t2lm_ie(t2lm, t2lm_action_frm);
ret_val = wlan_mlo_parse_t2lm_ie(t2lm, t2lm_action_frm,
frame_len);
}
return ret_val;
@@ -506,6 +524,7 @@ static QDF_STATUS wlan_mlo_parse_t2lm_response_action_frame(
int wlan_mlo_parse_t2lm_action_frame(
struct wlan_t2lm_onging_negotiation_info *t2lm,
struct wlan_action_frame *action_frm,
uint32_t frame_len,
enum wlan_t2lm_category category)
{
QDF_STATUS ret_val = QDF_STATUS_SUCCESS;
@@ -514,13 +533,13 @@ int wlan_mlo_parse_t2lm_action_frame(
case WLAN_T2LM_CATEGORY_REQUEST:
{
ret_val = wlan_mlo_parse_t2lm_request_action_frame(
t2lm, action_frm, category);
t2lm, action_frm, frame_len, category);
return qdf_status_to_os_return(ret_val);
}
case WLAN_T2LM_CATEGORY_RESPONSE:
{
ret_val = wlan_mlo_parse_t2lm_response_action_frame(
t2lm, action_frm, category);
t2lm, action_frm, frame_len, category);
return qdf_status_to_os_return(ret_val);
}