summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMukul Sharma <mukul@codeaurora.org>2017-06-21 12:35:09 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-07-05 00:12:42 -0700
commit0d54d236d3dc98eb05db03f162f39e9418eca07d (patch)
treed877d50dfde2ada168b6bf0d4bf7b2d91e5728ba
parentdff3b933b0df56cd3d01a80aae80aa2787bec870 (diff)
qcacld-2.0: Avoid OEM message overread
Propagation from qcacld-3.0 to qcacld-2.0 Currently in oem_cmd_handler() the CLD80211_ATTR_DATA is processed as an OEM message without first verifying that the payload has a sufficient length. This can lead to overreading the buffer. Add length checks to make sure the payload is large enough to hold the message it is supposed to encapsulate. Change-Id: Ifaa7d1cce5bd427bfeca14cab5a44c4cb72ce59f CRs-Fixed: 2058471
-rw-r--r--CORE/HDD/src/wlan_hdd_oemdata.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/CORE/HDD/src/wlan_hdd_oemdata.c b/CORE/HDD/src/wlan_hdd_oemdata.c
index c80a5a16f03b..2e6072fab834 100644
--- a/CORE/HDD/src/wlan_hdd_oemdata.c
+++ b/CORE/HDD/src/wlan_hdd_oemdata.c
@@ -1141,6 +1141,7 @@ static void oem_request_dispatcher(tAniMsgHdr *msg_hdr, int pid)
static void oem_cmd_handler(const void *data, int data_len, void *ctx, int pid)
{
tAniMsgHdr *msg_hdr;
+ int msg_len;
int ret;
struct nlattr *tb[CLD80211_ATTR_MAX + 1];
@@ -1150,6 +1151,10 @@ static void oem_cmd_handler(const void *data, int data_len, void *ctx, int pid)
return;
}
+ /*
+ * audit note: it is ok to pass a NULL policy here since only
+ * one attribute is parsed and it is explicitly validated
+ */
if (nla_parse(tb, CLD80211_ATTR_MAX, data, data_len, NULL)) {
hddLog(LOGE, FL("Invalid ATTR"));
return;
@@ -1160,15 +1165,22 @@ static void oem_cmd_handler(const void *data, int data_len, void *ctx, int pid)
return;
}
- msg_hdr = (tAniMsgHdr *)nla_data(tb[CLD80211_ATTR_DATA]);
- if (!msg_hdr) {
- hddLog(LOGE, FL("msg_hdr null"));
+ msg_len = nla_len(tb[CLD80211_ATTR_DATA]);
+ if (msg_len < sizeof(*msg_hdr)) {
+ hdd_err("runt ATTR_DATA size %d", msg_len);
send_oem_err_rsp_nlink_msg(pid, OEM_ERR_NULL_MESSAGE_HEADER);
return;
}
- oem_request_dispatcher(msg_hdr, pid);
- return;
+ msg_hdr = nla_data(tb[CLD80211_ATTR_DATA]);
+ if (msg_len < (sizeof(*msg_hdr) + msg_hdr->length)) {
+ hdd_err("Invalid nl msg len %d, msg hdr len %d",
+ msg_len, msg_hdr->length);
+ send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_MESSAGE_LENGTH);
+ return;
+ }
+
+ oem_request_dispatcher(msg_hdr, pid);
}
/**