nl80211: Support larger number of MAC ACL entries

If the maximum size of MAC ACL entries is large enough, the
configuration message may exceed the default buffer size of a netlink
message which is allocated with nlmsg_alloc(), and result in a failure
when putting the attributes into the message.

To fix this, calculate the required buffer size of the netlink message
according to MAC ACL size and allocate a sufficiently large buffer with
nlmsg_alloc_size().

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Yu Wang 2021-01-19 16:28:28 +08:00 committed by Jouni Malinen
parent f1fc9cf74e
commit 5f082c158c

View file

@ -656,12 +656,10 @@ struct nl_msg * nl80211_cmd_msg(struct i802_bss *bss, int flags, uint8_t cmd)
static struct nl_msg * static struct nl_msg *
nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex, nl80211_ifindex_msg_build(struct wpa_driver_nl80211_data *drv,
int flags, uint8_t cmd) struct nl_msg *msg, int ifindex, int flags,
uint8_t cmd)
{ {
struct nl_msg *msg;
msg = nlmsg_alloc();
if (!msg) if (!msg)
return NULL; return NULL;
@ -675,6 +673,15 @@ nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex,
} }
static struct nl_msg *
nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex,
int flags, uint8_t cmd)
{
return nl80211_ifindex_msg_build(drv, nlmsg_alloc(), ifindex, flags,
cmd);
}
struct nl_msg * nl80211_drv_msg(struct wpa_driver_nl80211_data *drv, int flags, struct nl_msg * nl80211_drv_msg(struct wpa_driver_nl80211_data *drv, int flags,
uint8_t cmd) uint8_t cmd)
{ {
@ -4151,6 +4158,7 @@ static int wpa_driver_nl80211_set_acl(void *priv,
struct nl_msg *acl; struct nl_msg *acl;
unsigned int i; unsigned int i;
int ret; int ret;
size_t acl_nla_sz, acl_nlmsg_sz, nla_sz, nlmsg_sz;
if (!(drv->capa.max_acl_mac_addrs)) if (!(drv->capa.max_acl_mac_addrs))
return -ENOTSUP; return -ENOTSUP;
@ -4161,7 +4169,9 @@ static int wpa_driver_nl80211_set_acl(void *priv,
wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)", wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
params->acl_policy ? "Accept" : "Deny", params->num_mac_acl); params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
acl = nlmsg_alloc(); acl_nla_sz = nla_total_size(ETH_ALEN) * params->num_mac_acl;
acl_nlmsg_sz = nlmsg_total_size(acl_nla_sz);
acl = nlmsg_alloc_size(acl_nlmsg_sz);
if (!acl) if (!acl)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < params->num_mac_acl; i++) { for (i = 0; i < params->num_mac_acl; i++) {
@ -4171,7 +4181,19 @@ static int wpa_driver_nl80211_set_acl(void *priv,
} }
} }
if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_MAC_ACL)) || /*
* genetlink message header (Length of user header is 0) +
* u32 attr: NL80211_ATTR_IFINDEX +
* u32 attr: NL80211_ATTR_ACL_POLICY +
* nested acl attr
*/
nla_sz = GENL_HDRLEN +
nla_total_size(4) * 2 +
nla_total_size(acl_nla_sz);
nlmsg_sz = nlmsg_total_size(nla_sz);
if (!(msg = nl80211_ifindex_msg_build(drv, nlmsg_alloc_size(nlmsg_sz),
drv->ifindex, 0,
NL80211_CMD_SET_MAC_ACL)) ||
nla_put_u32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ? nla_put_u32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
NL80211_ACL_POLICY_DENY_UNLESS_LISTED : NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED) || NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED) ||