nl80211: Check nla_put_nested() return value and handle errors

Couple of functions did not verify that nla_put_nested() succeeded. Fix
these by checking the return value and handling error cases cleanly.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2012-08-07 17:27:55 +03:00
parent 6afbc3d698
commit f0494d0f95

View file

@ -3479,23 +3479,15 @@ static int wpa_driver_nl80211_scan(void *priv,
{ {
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
int ret = 0, timeout; int ret = -1, timeout;
struct nl_msg *msg, *ssids, *freqs, *rates; struct nl_msg *msg, *ssids = NULL, *freqs = NULL, *rates = NULL;
size_t i; size_t i;
drv->scan_for_auth = 0; drv->scan_for_auth = 0;
msg = nlmsg_alloc(); msg = nlmsg_alloc();
ssids = nlmsg_alloc(); if (!msg)
freqs = nlmsg_alloc();
rates = nlmsg_alloc();
if (!msg || !ssids || !freqs || !rates) {
nlmsg_free(msg);
nlmsg_free(ssids);
nlmsg_free(freqs);
nlmsg_free(rates);
return -1; return -1;
}
os_free(drv->filter_ssids); os_free(drv->filter_ssids);
drv->filter_ssids = params->filter_ssids; drv->filter_ssids = params->filter_ssids;
@ -3506,6 +3498,10 @@ static int wpa_driver_nl80211_scan(void *priv,
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
if (params->num_ssids) {
ssids = nlmsg_alloc();
if (ssids == NULL)
goto nla_put_failure;
for (i = 0; i < params->num_ssids; i++) { for (i = 0; i < params->num_ssids; i++) {
wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID", wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
params->ssids[i].ssid, params->ssids[i].ssid,
@ -3513,8 +3509,9 @@ static int wpa_driver_nl80211_scan(void *priv,
NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len, NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len,
params->ssids[i].ssid); params->ssids[i].ssid);
} }
if (params->num_ssids) if (nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids) < 0)
nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids); goto nla_put_failure;
}
if (params->extra_ies) { if (params->extra_ies) {
wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs", wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
@ -3524,17 +3521,26 @@ static int wpa_driver_nl80211_scan(void *priv,
} }
if (params->freqs) { if (params->freqs) {
freqs = nlmsg_alloc();
if (freqs == NULL)
goto nla_put_failure;
for (i = 0; params->freqs[i]; i++) { for (i = 0; params->freqs[i]; i++) {
wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u " wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
"MHz", params->freqs[i]); "MHz", params->freqs[i]);
NLA_PUT_U32(freqs, i + 1, params->freqs[i]); NLA_PUT_U32(freqs, i + 1, params->freqs[i]);
} }
nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs); if (nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs) <
0)
goto nla_put_failure;
} }
if (params->p2p_probe) { if (params->p2p_probe) {
wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates"); wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
rates = nlmsg_alloc();
if (rates == NULL)
goto nla_put_failure;
/* /*
* Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
* by masking out everything else apart from the OFDM rates 6, * by masking out everything else apart from the OFDM rates 6,
@ -3543,7 +3549,9 @@ static int wpa_driver_nl80211_scan(void *priv,
*/ */
NLA_PUT(rates, NL80211_BAND_2GHZ, 8, NLA_PUT(rates, NL80211_BAND_2GHZ, 8,
"\x0c\x12\x18\x24\x30\x48\x60\x6c"); "\x0c\x12\x18\x24\x30\x48\x60\x6c");
nla_put_nested(msg, NL80211_ATTR_SCAN_SUPP_RATES, rates); if (nla_put_nested(msg, NL80211_ATTR_SCAN_SUPP_RATES, rates) <
0)
goto nla_put_failure;
NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE); NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
} }
@ -5655,7 +5663,8 @@ static int wpa_driver_nl80211_sta_add(void *priv,
NLA_PUT_U8(wme, NL80211_STA_WME_MAX_SP, NLA_PUT_U8(wme, NL80211_STA_WME_MAX_SP,
(params->qosinfo > WMM_QOSINFO_STA_SP_SHIFT) & (params->qosinfo > WMM_QOSINFO_STA_SP_SHIFT) &
WMM_QOSINFO_STA_SP_MASK); WMM_QOSINFO_STA_SP_MASK);
nla_put_nested(msg, NL80211_ATTR_STA_WME, wme); if (nla_put_nested(msg, NL80211_ATTR_STA_WME, wme) < 0)
goto nla_put_failure;
} }
ret = send_and_recv_msgs(drv, msg, NULL, NULL); ret = send_and_recv_msgs(drv, msg, NULL, NULL);
@ -8466,6 +8475,7 @@ static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
struct nl_msg *msg, *cqm = NULL; struct nl_msg *msg, *cqm = NULL;
int ret = -1;
wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d " wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
"hysteresis=%d", threshold, hysteresis); "hysteresis=%d", threshold, hysteresis);
@ -8484,19 +8494,16 @@ static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, threshold); NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, threshold);
NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hysteresis); NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hysteresis);
nla_put_nested(msg, NL80211_ATTR_CQM, cqm); if (nla_put_nested(msg, NL80211_ATTR_CQM, cqm) < 0)
goto nla_put_failure;
nlmsg_free(cqm); ret = send_and_recv_msgs(drv, msg, NULL, NULL);
cqm = NULL;
if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
return 0;
msg = NULL; msg = NULL;
nla_put_failure: nla_put_failure:
nlmsg_free(cqm); nlmsg_free(cqm);
nlmsg_free(msg); nlmsg_free(msg);
return -1; return ret;
} }