diff options
| author | Dustin Brown <dustinb@codeaurora.org> | 2017-10-17 11:46:19 -0700 |
|---|---|---|
| committer | snandini <snandini@codeaurora.org> | 2017-10-17 19:27:17 -0700 |
| commit | 6aadcd58b5cf78aa8281f34af6a73ba0f36e20bb (patch) | |
| tree | f365a5489bdd476745fa5609304b38da90c42e4f | |
| parent | bea0b10053c8cf6a093c936f3ad50c2ca1b8711c (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.c | 48 |
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 |
