diff options
author | Thomson Kang <thomson.kang@broadcom.corp-partner.google.com> | 2020-08-10 13:50:30 +0900 |
---|---|---|
committer | Ahmed ElArabawy <arabawy@google.com> | 2020-08-11 12:39:02 -0700 |
commit | 2c9abd7da3a09079a05f20a63f4bef6411fc7921 (patch) | |
tree | b906199efd776eeaeeca6570d22f30685d285eb0 | |
parent | 0b5e038c4d5c4f7a62b4416d4a936804103a661a (diff) | |
download | bcm43752-2c9abd7da3a09079a05f20a63f4bef6411fc7921.tar.gz |
bcmdhd: Fixed slab-out-of-bound issue for PNO logging.
issues)
1. event_data is allocated to 38 bytes, payload_len is 50.
So, copy to the debug ring buffer exceed the event_data size in dhd_dbg_ring_push.
2. event_data->tlvs is allocated to 12 bytes, but copy to tlvs greater than 24 (SSID up to 32, rssi(2) and channel(2)).
fixed)
1. Chnaged the allocated event_data size from 38 to 50.
2. Changed event_data->tlvs type from pointer to zero value array for making continuous array.
Note :
Added define LINUX for log_conn_event_t because of compile error happened for Windows driver of all compile verification.
Bug: 161418541
Test: Manual
Signed-off-by: Thomson Kang <thomson.kang@broadcom.corp-partner.google.com>
Change-Id: I8270584adb922357f77d57e37fcd7a5faf344f97
Signed-off-by: Ahmed ElArabawy <arabawy@google.com>
-rwxr-xr-x | dhd_debug.h | 4 | ||||
-rwxr-xr-x | wl_cfgscan.c | 60 |
2 files changed, 15 insertions, 49 deletions
diff --git a/dhd_debug.h b/dhd_debug.h index c7a1717..1c0b350 100755 --- a/dhd_debug.h +++ b/dhd_debug.h @@ -293,9 +293,10 @@ typedef struct per_packet_status_entry { #define PACKED_STRUCT __attribute__ ((packed)) +#if defined(LINUX) typedef struct log_conn_event { uint16 event; - tlv_log *tlvs; + tlv_log tlvs[0]; /* * separate parameter structure per event to be provided and optional data * the event_data is expected to include an official android part, with some @@ -304,6 +305,7 @@ typedef struct log_conn_event { * understood by the developer only. */ } PACKED_STRUCT log_conn_event_t; +#endif /* defined(LINUX) */ /* * Ring buffer name for power events ring. note that power event are extremely frequents diff --git a/wl_cfgscan.c b/wl_cfgscan.c index 1afa642..c7fcb49 100755 --- a/wl_cfgscan.c +++ b/wl_cfgscan.c @@ -302,7 +302,7 @@ s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi, bool updat dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub); log_conn_event_t *event_data = NULL; tlv_log *tlv_data = NULL; - u32 alloc_len, tlv_len; + u32 alloc_len; u32 payload_len; s32 mgmt_type; s32 signal; @@ -414,7 +414,8 @@ s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi, bool updat if (DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID) && (cfg->sched_scan_req && !cfg->scan_request)) { - alloc_len = sizeof(log_conn_event_t) + IEEE80211_MAX_SSID_LEN + sizeof(uint16) + + alloc_len = sizeof(log_conn_event_t) + (3 * sizeof(tlv_log)) + + IEEE80211_MAX_SSID_LEN + sizeof(uint16) + sizeof(int16); event_data = (log_conn_event_t *)MALLOCZ(dhdp->osh, alloc_len); if (!event_data) { @@ -422,13 +423,6 @@ s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi, bool updat "length(%d)\n", __func__, alloc_len)); goto out_err; } - tlv_len = 3 * sizeof(tlv_log); - event_data->tlvs = (tlv_log *)MALLOCZ(cfg->osh, tlv_len); - if (!event_data->tlvs) { - WL_ERR(("%s: failed to allocate the log_conn_event_t with " - "length(%d)\n", __func__, tlv_len)); - goto free_evt_data; - } payload_len = sizeof(log_conn_event_t); event_data->event = WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND; @@ -457,8 +451,6 @@ s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi, bool updat dhd_os_push_push_ring_data(dhdp, DHD_EVENT_RING_ID, event_data, payload_len); - MFREE(dhdp->osh, event_data->tlvs, tlv_len); -free_evt_data: MFREE(dhdp->osh, event_data, alloc_len); } @@ -3404,7 +3396,7 @@ wl_cfg80211_sched_scan_start(struct wiphy *wiphy, struct cfg80211_ssid *hidden_ssid_list = NULL; log_conn_event_t *event_data = NULL; tlv_log *tlv_data = NULL; - u32 alloc_len = 0, tlv_len = 0; + u32 alloc_len = 0; u32 payload_len; int ssid_cnt = 0; int i; @@ -3453,23 +3445,13 @@ wl_cfg80211_sched_scan_start(struct wiphy *wiphy, } if (DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID)) { - alloc_len = sizeof(log_conn_event_t) + DOT11_MAX_SSID_LEN; - event_data = (log_conn_event_t *)MALLOC(cfg->osh, alloc_len); + alloc_len = sizeof(log_conn_event_t) + sizeof(tlv_log) + DOT11_MAX_SSID_LEN; + event_data = (log_conn_event_t *)MALLOCZ(cfg->osh, alloc_len); if (!event_data) { WL_ERR(("%s: failed to allocate log_conn_event_t with " "length(%d)\n", __func__, alloc_len)); return -ENOMEM; } - bzero(event_data, alloc_len); - event_data->tlvs = NULL; - tlv_len = sizeof(tlv_log); - event_data->tlvs = (tlv_log *)MALLOC(cfg->osh, tlv_len); - if (!event_data->tlvs) { - WL_ERR(("%s: failed to allocate log_tlv with " - "length(%d)\n", __func__, tlv_len)); - MFREE(cfg->osh, event_data, alloc_len); - return -ENOMEM; - } } for (i = 0; i < request->n_match_sets && ssid_cnt < MAX_PFN_LIST_COUNT; i++) { ssid = &request->match_sets[i].ssid; @@ -3556,7 +3538,6 @@ wl_cfg80211_sched_scan_start(struct wiphy *wiphy, exit: if (event_data) { - MFREE(cfg->osh, event_data->tlvs, tlv_len); MFREE(cfg->osh, event_data, alloc_len); } return ret; @@ -3851,7 +3832,7 @@ wl_notify_sched_scan_results(struct bcm_cfg80211 *cfg, struct net_device *ndev, int n_pfn_results = 0; log_conn_event_t *event_data = NULL; tlv_log *tlv_data = NULL; - u32 alloc_len = 0, tlv_len = 0; + u32 alloc_len = 0; u32 payload_len; u8 tmp_buf[DOT11_MAX_SSID_LEN + 1]; @@ -3894,21 +3875,14 @@ wl_notify_sched_scan_results(struct bcm_cfg80211 *cfg, struct net_device *ndev, request->wiphy = wiphy; if (DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID)) { - alloc_len = sizeof(log_conn_event_t) + DOT11_MAX_SSID_LEN + - sizeof(uint16) + sizeof(int16); - event_data = (log_conn_event_t *)MALLOC(cfg->osh, alloc_len); + alloc_len = sizeof(log_conn_event_t) + (3 * sizeof(tlv_log)) + + DOT11_MAX_SSID_LEN + sizeof(uint16) + sizeof(int16); + event_data = (log_conn_event_t *)MALLOCZ(cfg->osh, alloc_len); if (!event_data) { WL_ERR(("%s: failed to allocate the log_conn_event_t with " "length(%d)\n", __func__, alloc_len)); goto out_err; } - tlv_len = 3 * sizeof(tlv_log); - event_data->tlvs = (tlv_log *)MALLOC(cfg->osh, tlv_len); - if (!event_data->tlvs) { - WL_ERR(("%s: failed to allocate the tlv_log with " - "length(%d)\n", __func__, tlv_len)); - goto out_err; - } } for (i = 0; i < n_pfn_results; i++) { @@ -4053,21 +4027,14 @@ wl_notify_sched_scan_results(struct bcm_cfg80211 *cfg, struct net_device *ndev, request->wiphy = wiphy; if (DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID)) { - alloc_len = sizeof(log_conn_event_t) + DOT11_MAX_SSID_LEN + - sizeof(uint16) + sizeof(int16); + alloc_len = sizeof(log_conn_event_t) + (3 * sizeof(tlv_log)) + + DOT11_MAX_SSID_LEN + sizeof(uint16) + sizeof(int16); event_data = (log_conn_event_t *)MALLOC(cfg->osh, alloc_len); if (!event_data) { WL_ERR(("%s: failed to allocate the log_conn_event_t with " "length(%d)\n", __func__, alloc_len)); goto out_err; } - tlv_len = 3 * sizeof(tlv_log); - event_data->tlvs = (tlv_log *)MALLOC(cfg->osh, tlv_len); - if (!event_data->tlvs) { - WL_ERR(("%s: failed to allocate the tlv_log with " - "length(%d)\n", __func__, tlv_len)); - goto out_err; - } } for (i = 0; i < n_pfn_results; i++) { @@ -4207,9 +4174,6 @@ out_err: } if (event_data) { - if (event_data->tlvs) { - MFREE(cfg->osh, event_data->tlvs, tlv_len); - } MFREE(cfg->osh, event_data, alloc_len); } return err; |