wireless-drivers: Dynamically allocate struct station_info
Since the addition of the TXQ stats to cfg80211, the station_info struct
has grown to be quite large, which results in warnings when allocated on
the stack. Fix the affected places to do dynamic allocations instead.
Fixes: 52539ca89f
("cfg80211: Expose TXQ stats and parameters to userspace")
Reviewed-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:

committed by
Kalle Valo

parent
4f9fb99001
commit
41bd3d585d
@@ -34,12 +34,13 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
{
|
||||
const u8 *sta_addr;
|
||||
u16 frame_control;
|
||||
struct station_info sinfo = { 0 };
|
||||
struct station_info *sinfo;
|
||||
size_t payload_len;
|
||||
u16 tlv_type;
|
||||
u16 tlv_value_len;
|
||||
size_t tlv_full_len;
|
||||
const struct qlink_tlv_hdr *tlv;
|
||||
int ret = 0;
|
||||
|
||||
if (unlikely(len < sizeof(*sta_assoc))) {
|
||||
pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
|
||||
@@ -53,6 +54,10 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
|
||||
if (!sinfo)
|
||||
return -ENOMEM;
|
||||
|
||||
sta_addr = sta_assoc->sta_addr;
|
||||
frame_control = le16_to_cpu(sta_assoc->frame_control);
|
||||
|
||||
@@ -61,9 +66,9 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
|
||||
qtnf_sta_list_add(vif, sta_addr);
|
||||
|
||||
sinfo.assoc_req_ies = NULL;
|
||||
sinfo.assoc_req_ies_len = 0;
|
||||
sinfo.generation = vif->generation;
|
||||
sinfo->assoc_req_ies = NULL;
|
||||
sinfo->assoc_req_ies_len = 0;
|
||||
sinfo->generation = vif->generation;
|
||||
|
||||
payload_len = len - sizeof(*sta_assoc);
|
||||
tlv = (const struct qlink_tlv_hdr *)sta_assoc->ies;
|
||||
@@ -73,23 +78,27 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
tlv_value_len = le16_to_cpu(tlv->len);
|
||||
tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr);
|
||||
|
||||
if (tlv_full_len > payload_len)
|
||||
return -EINVAL;
|
||||
if (tlv_full_len > payload_len) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tlv_type == QTN_TLV_ID_IE_SET) {
|
||||
const struct qlink_tlv_ie_set *ie_set;
|
||||
unsigned int ie_len;
|
||||
|
||||
if (payload_len < sizeof(*ie_set))
|
||||
return -EINVAL;
|
||||
if (payload_len < sizeof(*ie_set)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ie_set = (const struct qlink_tlv_ie_set *)tlv;
|
||||
ie_len = tlv_value_len -
|
||||
(sizeof(*ie_set) - sizeof(ie_set->hdr));
|
||||
|
||||
if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) {
|
||||
sinfo.assoc_req_ies = ie_set->ie_data;
|
||||
sinfo.assoc_req_ies_len = ie_len;
|
||||
sinfo->assoc_req_ies = ie_set->ie_data;
|
||||
sinfo->assoc_req_ies_len = ie_len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,13 +106,17 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len);
|
||||
}
|
||||
|
||||
if (payload_len)
|
||||
return -EINVAL;
|
||||
if (payload_len) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, &sinfo,
|
||||
cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, sinfo,
|
||||
GFP_KERNEL);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
kfree(sinfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
Reference in New Issue
Block a user