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 <quic_vganneva@quicinc.com>
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 @@
     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 @@
     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 @@
        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 @@
          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