From 8536ce5d51700f7fe39ea33c4ce3d56b919b83cf Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Tue, 9 Jan 2024 15:58:36 +0530 Subject: [PATCH] qcacmn: Fix OOB read of ML IE In util_get_bvmlie_bssparamchangecnt() and util_get_bvmlie_mldcap(), fix the possible OOB read of the ML IE, if the ML IE length is less than the minimum template of Basic variant ML probe response. Change-Id: I50efaba682a1e42ef8befe09224edc34de9c8c7b CRs-Fixed: 3700045 --- umac/mlo_mgr/src/utils_mlo.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/umac/mlo_mgr/src/utils_mlo.c b/umac/mlo_mgr/src/utils_mlo.c index 27f4661b37..3311151655 100644 --- a/umac/mlo_mgr/src/utils_mlo.c +++ b/umac/mlo_mgr/src/utils_mlo.c @@ -4057,6 +4057,27 @@ util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq, return QDF_STATUS_SUCCESS; } +static inline QDF_STATUS +util_validate_bv_mlie_min_seq_len(qdf_size_t mlieseqlen) +{ + qdf_size_t parsed_len = sizeof(struct wlan_ie_multilink); + + if (mlieseqlen < parsed_len + WLAN_ML_BV_CINFO_LENGTH_SIZE) { + mlo_err_rl("ML seq payload of len %zu doesn't accommodate the mandatory BV ML IE Common info len field", + mlieseqlen); + return QDF_STATUS_E_PROTO; + } + parsed_len += WLAN_ML_BV_CINFO_LENGTH_SIZE; + + if (mlieseqlen < parsed_len + QDF_MAC_ADDR_SIZE) { + mlo_err_rl("ML seq payload of len %zu doesn't accommodate the mandatory MLD addr", + mlieseqlen); + return QDF_STATUS_E_PROTO; + } + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS util_find_mlie_by_variant(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq, qdf_size_t *mlieseqlen, int variant) @@ -4195,6 +4216,9 @@ util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen, presencebitmap = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX, WLAN_ML_CTRL_PBM_BITS); + if (QDF_IS_STATUS_ERROR(util_validate_bv_mlie_min_seq_len(mlieseqlen))) + return QDF_STATUS_E_INVAL; + commoninfo = mlieseq + sizeof(struct wlan_ie_multilink); commoninfolen = *(mlieseq + sizeof(struct wlan_ie_multilink)); @@ -4584,6 +4608,9 @@ util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen, presencebitmap = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX, WLAN_ML_CTRL_PBM_BITS); + if (QDF_IS_STATUS_ERROR(util_validate_bv_mlie_min_seq_len(mlieseqlen))) + return QDF_STATUS_E_INVAL; + commoninfo = mlieseq + sizeof(struct wlan_ie_multilink); commoninfo_len = *(mlieseq + sizeof(struct wlan_ie_multilink)); /* mldcap_offset stores the offset of MLD Capabilities within