From 9266c2d2712cff22ebd599ad77333fe6cb29ccf9 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Thu, 20 Apr 2023 11:58:34 +0530 Subject: [PATCH] qcacmn: Fix cm req accessed outside cm req or CM lock wlan_cm_get_rnr, uses the cm request without lock and pass the pointer to the caller instead of passing a copy. Fix it by copying the rnr info while holding the lock. and move the cm req access logic to core from dispatcher. Change-Id: I72861021d98b996a379a2917874b5dadbc37c6af CRs-Fixed: 3483871 --- .../core/src/wlan_cm_main_api.h | 11 +++++ .../connection_mgr/core/src/wlan_cm_util.c | 41 +++++++++++++++++++ .../dispatcher/inc/wlan_cm_api.h | 7 ++-- .../dispatcher/src/wlan_cm_api.c | 21 ++-------- 4 files changed, 60 insertions(+), 20 deletions(-) diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h b/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h index da69fc2bc4..186feba1cc 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h @@ -1303,6 +1303,17 @@ void cm_set_candidate_custom_sort_cb( */ bool cm_is_connect_req_reassoc(struct wlan_cm_connect_req *req); +/** + * cm_get_rnr() - get rnr + * @vdev:vdev + * @cm_id: connect mgr id + * @rnr: pointer to copy rnr info + * + * Return: QDF_STATUS + */ +QDF_STATUS cm_get_rnr(struct wlan_objmgr_vdev *vdev, wlan_cm_id cm_id, + struct reduced_neighbor_report *rnr); + #ifdef CONN_MGR_ADV_FEATURE /** * cm_free_connect_rsp_ies() - Function to free all connection IEs. diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_util.c b/umac/mlme/connection_mgr/core/src/wlan_cm_util.c index fee47dec0e..a8362ced65 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_util.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_util.c @@ -1652,6 +1652,47 @@ wlan_cm_id cm_get_cm_id_by_scan_id(struct cnx_mgr *cm_ctx, return CM_ID_INVALID; } +QDF_STATUS cm_get_rnr(struct wlan_objmgr_vdev *vdev, wlan_cm_id cm_id, + struct reduced_neighbor_report *rnr) +{ + qdf_list_node_t *cur_node = NULL, *next_node = NULL; + struct cm_req *cm_req; + uint32_t prefix = CM_ID_GET_PREFIX(cm_id); + struct cnx_mgr *cm_ctx; + + if (prefix != CONNECT_REQ_PREFIX) + return QDF_STATUS_E_INVAL; + + cm_ctx = cm_get_cm_ctx(vdev); + if (!cm_ctx) + return QDF_STATUS_E_INVAL; + + cm_req_lock_acquire(cm_ctx); + qdf_list_peek_front(&cm_ctx->req_list, &cur_node); + while (cur_node) { + qdf_list_peek_next(&cm_ctx->req_list, cur_node, &next_node); + cm_req = qdf_container_of(cur_node, struct cm_req, node); + + if (cm_req->cm_id == cm_id) { + if (!cm_req->connect_req.cur_candidate || + !cm_req->connect_req.cur_candidate->entry) + break; + + qdf_mem_copy(rnr, + &cm_req->connect_req.cur_candidate->entry->rnr, + sizeof(*rnr)); + cm_req_lock_release(cm_ctx); + return QDF_STATUS_SUCCESS; + } + + cur_node = next_node; + next_node = NULL; + } + cm_req_lock_release(cm_ctx); + + return QDF_STATUS_E_FAILURE; +} + #ifdef WLAN_POLICY_MGR_ENABLE static void cm_get_pcl_chan_weigtage_for_sta(struct wlan_objmgr_pdev *pdev, diff --git a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h index 14c7c8dc5e..175e733e09 100644 --- a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h +++ b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h @@ -500,11 +500,12 @@ void wlan_cm_set_candidate_custom_sort_cb( * wlan_cm_get_rnr() - get rnr * @vdev:vdev * @cm_id: connect mgr id + * @rnr: pointer to copy rnr info * - * Return: rnr pointer + * Return: QDF_STATUS */ -struct reduced_neighbor_report *wlan_cm_get_rnr(struct wlan_objmgr_vdev *vdev, - wlan_cm_id cm_id); +QDF_STATUS wlan_cm_get_rnr(struct wlan_objmgr_vdev *vdev, wlan_cm_id cm_id, + struct reduced_neighbor_report *rnr); /** * wlan_cm_disc_cont_after_rso_stop() - Continue disconnect after RSO stop diff --git a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c index 69dfe7b74b..53921986bc 100644 --- a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c +++ b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c @@ -351,31 +351,18 @@ void wlan_cm_set_candidate_custom_sort_cb( #endif -struct reduced_neighbor_report *wlan_cm_get_rnr(struct wlan_objmgr_vdev *vdev, - wlan_cm_id cm_id) +QDF_STATUS wlan_cm_get_rnr(struct wlan_objmgr_vdev *vdev, wlan_cm_id cm_id, + struct reduced_neighbor_report *rnr) { enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); - struct cm_req *cm_req; - struct cnx_mgr *cm_ctx; if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) { mlme_err("vdev %d Invalid mode %d", wlan_vdev_get_id(vdev), op_mode); - return NULL; + return QDF_STATUS_E_NOSUPPORT; } - cm_ctx = cm_get_cm_ctx(vdev); - if (!cm_ctx) - return NULL; - cm_req = cm_get_req_by_cm_id(cm_ctx, cm_id); - if (!cm_req) - return NULL; - - if (cm_req->connect_req.cur_candidate && - cm_req->connect_req.cur_candidate->entry) - return &cm_req->connect_req.cur_candidate->entry->rnr; - - return NULL; + return cm_get_rnr(vdev, cm_id, rnr); } void