mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
171 lines
5.9 KiB
Diff
171 lines
5.9 KiB
Diff
|
From b5112838eb91b71eded4b5ee37338535784e0aef Mon Sep 17 00:00:00 2001
|
||
|
From: Srinivas Girigowda <sgirigow@qca.qualcomm.com>
|
||
|
Date: Sun, 10 Apr 2016 00:03:18 -0700
|
||
|
Subject: qcacld-2.0: Add input validation for SENDACTIONFRAME
|
||
|
|
||
|
Add input validation for SENDACTIONFRAME driver command.
|
||
|
|
||
|
Change-Id: I3d1bf424e5e0f9a3b6f4662dd12a3a7314c7eace
|
||
|
CRs-Fixed: 1001449
|
||
|
---
|
||
|
CORE/HDD/src/wlan_hdd_main.c | 97 +++++++++++++++++++++++++++-----------------
|
||
|
1 file changed, 59 insertions(+), 38 deletions(-)
|
||
|
|
||
|
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
|
||
|
index a647bb5..8b7a441 100644
|
||
|
--- a/CORE/HDD/src/wlan_hdd_main.c
|
||
|
+++ b/CORE/HDD/src/wlan_hdd_main.c
|
||
|
@@ -2205,16 +2205,15 @@ hdd_parse_send_action_frame_v1_data(const tANI_U8 *pValue,
|
||
|
static int
|
||
|
hdd_sendactionframe(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
|
||
|
const tANI_U8 channel, const tANI_U8 dwell_time,
|
||
|
- const tANI_U8 payload_len, const tANI_U8 *payload)
|
||
|
+ const int payload_len, const tANI_U8 *payload)
|
||
|
{
|
||
|
struct ieee80211_channel chan;
|
||
|
- tANI_U8 frame_len;
|
||
|
+ int frame_len, ret = 0;
|
||
|
tANI_U8 *frame;
|
||
|
struct ieee80211_hdr_3addr *hdr;
|
||
|
u64 cookie;
|
||
|
hdd_station_ctx_t *pHddStaCtx;
|
||
|
hdd_context_t *pHddCtx;
|
||
|
- int ret = 0;
|
||
|
tpSirMacVendorSpecificFrameHdr pVendorSpecific =
|
||
|
(tpSirMacVendorSpecificFrameHdr) payload;
|
||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) || defined(WITH_BACKPORTS)
|
||
|
@@ -2371,45 +2370,57 @@ hdd_parse_sendactionframe_v1(hdd_adapter_t *pAdapter, const char *command)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
-/*
|
||
|
- \brief hdd_parse_sendactionframe_v2() - parse version 2 of the
|
||
|
- SENDACTIONFRAME command
|
||
|
-
|
||
|
- This function parses the v2 SENDACTIONFRAME command with the format
|
||
|
+/**
|
||
|
+ * hdd_parse_sendactionframe_v2() - parse version 2 of the
|
||
|
+ * SENDACTIONFRAME command
|
||
|
+ * @pAdapter: Adapter upon which the command was received
|
||
|
+ * @command: command that was received, ASCII command followed
|
||
|
+ * by binary data
|
||
|
+ * @total_len: total length of command
|
||
|
+ *
|
||
|
+ * This function parses the v2 SENDACTIONFRAME command with the format
|
||
|
+ * SENDACTIONFRAME <android_wifi_af_params>
|
||
|
+ *
|
||
|
+ * Return: 0 for success non-zero for failure
|
||
|
+ */
|
||
|
+static int
|
||
|
+hdd_parse_sendactionframe_v2(hdd_adapter_t *pAdapter,
|
||
|
+ const char *command, int total_len)
|
||
|
+{
|
||
|
+ struct android_wifi_af_params *params;
|
||
|
+ tSirMacAddr bssid;
|
||
|
+ int ret;
|
||
|
|
||
|
- SENDACTIONFRAME <android_wifi_af_params>
|
||
|
+ /* The params are located after "SENDACTIONFRAME " */
|
||
|
+ total_len -= 16;
|
||
|
+ params = (struct android_wifi_af_params *)(command + 16);
|
||
|
|
||
|
- \param - pAdapter - Adapter upon which the command was received
|
||
|
- \param - command - command that was received, ASCII command followed
|
||
|
- by binary data
|
||
|
+ if (params->len <= 0 || params->len > ANDROID_WIFI_ACTION_FRAME_SIZE ||
|
||
|
+ (params->len > total_len)) {
|
||
|
+ hddLog(LOGE, FL("Invalid payload length: %d"), params->len);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
|
||
|
- \return - 0 for success non-zero for failure
|
||
|
+ if (!mac_pton(params->bssid, (u8 *)&bssid)) {
|
||
|
+ hddLog(LOGE, FL("MAC address parsing failed"));
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
|
||
|
- --------------------------------------------------------------------------*/
|
||
|
-static int
|
||
|
-hdd_parse_sendactionframe_v2(hdd_adapter_t *pAdapter,
|
||
|
- const char *command)
|
||
|
-{
|
||
|
- struct android_wifi_af_params *params;
|
||
|
- tSirMacAddr bssid;
|
||
|
- int ret;
|
||
|
+ if (params->channel < 0 ||
|
||
|
+ params->channel > WNI_CFG_CURRENT_CHANNEL_STAMAX) {
|
||
|
+ hddLog(LOGE, FL("Invalid channel: %d"), params->channel);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
|
||
|
- /* params are large so keep off the stack */
|
||
|
- params = kmalloc(sizeof(*params), GFP_KERNEL);
|
||
|
- if (!params) return -ENOMEM;
|
||
|
+ if (params->dwell_time < 0) {
|
||
|
+ hddLog(LOGE, FL("Invalid dwell_time: %d"), params->dwell_time);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
|
||
|
- /* The params are located after "SENDACTIONFRAME " */
|
||
|
- memcpy(params, command + 16, sizeof(*params));
|
||
|
+ ret = hdd_sendactionframe(pAdapter, bssid, params->channel,
|
||
|
+ params->dwell_time, params->len, params->data);
|
||
|
|
||
|
- if (!mac_pton(params->bssid, (u8 *)&bssid)) {
|
||
|
- hddLog(LOGE, "%s: MAC address parsing failed", __func__);
|
||
|
- ret = -EINVAL;
|
||
|
- } else {
|
||
|
- ret = hdd_sendactionframe(pAdapter, bssid, params->channel,
|
||
|
- params->dwell_time, params->len, params->data);
|
||
|
- }
|
||
|
- kfree(params);
|
||
|
- return ret;
|
||
|
+ return ret;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
@@ -2429,7 +2440,8 @@ hdd_parse_sendactionframe_v2(hdd_adapter_t *pAdapter,
|
||
|
|
||
|
--------------------------------------------------------------------------*/
|
||
|
static int
|
||
|
-hdd_parse_sendactionframe(hdd_adapter_t *pAdapter, const char *command)
|
||
|
+hdd_parse_sendactionframe(hdd_adapter_t *pAdapter, const char *command,
|
||
|
+ int total_len)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
@@ -2445,11 +2457,19 @@ hdd_parse_sendactionframe(hdd_adapter_t *pAdapter, const char *command)
|
||
|
* SENDACTIONFRAME xx:xx:xx:xx:xx:xx*
|
||
|
* 111111111122222222223333
|
||
|
* 0123456789012345678901234567890123
|
||
|
+ *
|
||
|
+ * For both the commands, a valid command must have atleast first 34 length
|
||
|
+ * of data.
|
||
|
*/
|
||
|
+ if (total_len < 34) {
|
||
|
+ hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
if (command[33]) {
|
||
|
ret = hdd_parse_sendactionframe_v1(pAdapter, command);
|
||
|
} else {
|
||
|
- ret = hdd_parse_sendactionframe_v2(pAdapter, command);
|
||
|
+ ret = hdd_parse_sendactionframe_v2(pAdapter, command, total_len);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
@@ -5851,7 +5871,8 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
|
||
|
}
|
||
|
else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
|
||
|
{
|
||
|
- ret = hdd_parse_sendactionframe(pAdapter, command);
|
||
|
+ ret = hdd_parse_sendactionframe(pAdapter, command,
|
||
|
+ priv_data.total_len);
|
||
|
}
|
||
|
else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
|
||
|
{
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|