From 117593cf89e3d1fc796ff4f8a8d66f0aa4c13b28 Mon Sep 17 00:00:00 2001 From: Vinay Gannevaram Date: Mon, 2 Mar 2020 18:36:58 +0530 Subject: WifiHal: Fix OOB read of ctrl buf while registering monitor sock Boundary check for NLMSG length is not present, which would result in OOB read of the buffer during nla parse. Hence add required boundary checks before processing ctrl msg from wifihal clients. Also allocate required buffer for control events to the size of received nlmsg data Bug: 149836664 Test: Manual - Basic wifi sanity test CRs-Fixed: 2628103 Change-Id: Idc971a343f30e41f359180757f108a8c0dfe2a7e Signed-off-by: Vinay Gannevaram --- qcwcn/wifi_hal/wifi_hal.cpp | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'qcwcn/wifi_hal') diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp index 61f7ee6..3b21a0e 100644 --- a/qcwcn/wifi_hal/wifi_hal.cpp +++ b/qcwcn/wifi_hal/wifi_hal.cpp @@ -1054,6 +1054,11 @@ static int validate_cld80211_msg(nlmsghdr *nlh, int family, int cmd) struct genlmsghdr *hdr; hdr = (genlmsghdr *)nlmsg_data(nlh); + if (nlh->nlmsg_len > DEFAULT_PAGE_SIZE - sizeof(wifihal_ctrl_req_t)) + { + ALOGE("%s: Invalid nlmsg length", __FUNCTION__); + return -1; + } if(hdr->cmd == WLAN_NL_MSG_OEM) { ALOGV("%s: FAMILY ID : %d ,NL CMD : %d received", __FUNCTION__, @@ -1077,6 +1082,11 @@ static int validate_genl_msg(nlmsghdr *nlh, int family, int cmd) struct genlmsghdr *hdr; hdr = (genlmsghdr *)nlmsg_data(nlh); + if (nlh->nlmsg_len > DEFAULT_PAGE_SIZE - sizeof(wifihal_ctrl_req_t)) + { + ALOGE("%s: Invalid nlmsg length", __FUNCTION__); + return -1; + } if(hdr->cmd == NL80211_CMD_FRAME || hdr->cmd == NL80211_CMD_REGISTER_ACTION) { @@ -1194,9 +1204,17 @@ static int register_monitor_sock(wifi_handle handle, wifihal_ctrl_req_t *ctrl_ms genlh = (struct genlmsghdr *)nlmsg_data(nlh); struct nlattr *nlattrs[NL80211_ATTR_MAX + 1]; - nla_parse(nlattrs, NL80211_ATTR_MAX, genlmsg_attrdata(genlh, 0), - genlmsg_attrlen(genlh, 0), NULL); - + if (nlh->nlmsg_len > DEFAULT_PAGE_SIZE - sizeof(*ctrl_msg)) + { + ALOGE("%s: Invalid nlmsg length", __FUNCTION__); + return -1; + } + if (nla_parse(nlattrs, NL80211_ATTR_MAX, genlmsg_attrdata(genlh, 0), + genlmsg_attrlen(genlh, 0), NULL)) + { + ALOGE("unable to parse nl attributes"); + return -1; + } if (!nlattrs[NL80211_ATTR_FRAME_TYPE]) { ALOGD("No Valid frame type"); @@ -1555,18 +1573,17 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg) ALOGD("No Frame body"); return WIFI_SUCCESS; } - - ctrl_evt = (wifihal_ctrl_event_t *)malloc(DEFAULT_PAGE_SIZE); + ctrl_evt = (wifihal_ctrl_event_t *)malloc(sizeof(*ctrl_evt) + nlh->nlmsg_len); if(ctrl_evt == NULL) { ALOGE("Memory allocation failure"); return -1; } - memset((char *)ctrl_evt, 0, DEFAULT_PAGE_SIZE); + memset((char *)ctrl_evt, 0, sizeof(*ctrl_evt) + nlh->nlmsg_len); ctrl_evt->family_name = GENERIC_NL_FAMILY; ctrl_evt->cmd_id = cmd; - ctrl_evt->data_len = msg->nm_nlh->nlmsg_len; - memcpy(ctrl_evt->data, (char *)msg->nm_nlh, ctrl_evt->data_len); + ctrl_evt->data_len = nlh->nlmsg_len; + memcpy(ctrl_evt->data, (char *)nlh, ctrl_evt->data_len); buff = (char *)nla_data(nlattrs[NL80211_ATTR_FRAME]) + 24; //! Size of Wlan80211FrameHeader -- cgit v1.2.3