summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDustin Brown <dustinb@codeaurora.org>2017-10-17 11:46:19 -0700
committersnandini <snandini@codeaurora.org>2017-10-17 19:27:17 -0700
commit6aadcd58b5cf78aa8281f34af6a73ba0f36e20bb (patch)
treef365a5489bdd476745fa5609304b38da90c42e4f
parentbea0b10053c8cf6a093c936f3ad50c2ca1b8711c (diff)
qcacld-3.0: Avoid buffer overrun via null termination
__iw_softap_set_ini_cfg assumes a given user supplied buffer is null terminated, which can lead to a buffer overrun. Ensure the buffer is null terminated by copying it to a new, oversized buffer whose last byte is zero. Change-Id: If94e753026f79a368cd6b9cb7c745ade4ae29452 CRs-Fixed: 2118809
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index e0ef0ec72a46..72949479c9fd 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -2761,30 +2761,44 @@ void hdd_sap_restart_with_channel_switch(hdd_adapter_t *ap_adapter,
}
#endif
-int
-static __iw_softap_set_ini_cfg(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int __iw_softap_set_ini_cfg(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- QDF_STATUS vstatus;
- int ret = 0; /* success */
- hdd_adapter_t *pAdapter = (netdev_priv(dev));
- hdd_context_t *pHddCtx;
+ QDF_STATUS status;
+ int errno;
+ hdd_adapter_t *adapter;
+ hdd_context_t *hdd_ctx;
+ char *value;
+ size_t len;
ENTER_DEV(dev);
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- ret = wlan_hdd_validate_context(pHddCtx);
- if (ret)
- return ret;
+ adapter = netdev_priv(dev);
+ errno = hdd_validate_adapter(adapter);
+ if (errno)
+ return errno;
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ errno = wlan_hdd_validate_context(hdd_ctx);
+ if (errno)
+ return errno;
- hdd_debug("Received data %s", extra);
+ /* ensure null termination */
+ len = min_t(size_t, wrqu->data.length, QCSAP_IOCTL_MAX_STR_LEN);
+ value = qdf_mem_malloc(len + 1);
+ if (!value)
+ return -ENOMEM;
- vstatus = hdd_execute_global_config_command(pHddCtx, extra);
- if (QDF_STATUS_SUCCESS != vstatus)
- ret = -EINVAL;
+ qdf_mem_copy(value, extra, len);
+ hdd_debug("Received data %s", value);
+ status = hdd_execute_global_config_command(hdd_ctx, value);
+ qdf_mem_free(value);
- return ret;
+ EXIT();
+
+ return qdf_status_to_os_return(status);
}
int