From 5f082c158c49a23614b69e4465e9a7299f004f5f Mon Sep 17 00:00:00 2001 From: Yu Wang Date: Tue, 19 Jan 2021 16:28:28 +0800 Subject: [PATCH] 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 --- src/drivers/driver_nl80211.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 5c56b0422..ed194be2a 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -656,12 +656,10 @@ struct nl_msg * nl80211_cmd_msg(struct i802_bss *bss, int flags, uint8_t cmd) static struct nl_msg * -nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex, - int flags, uint8_t cmd) +nl80211_ifindex_msg_build(struct wpa_driver_nl80211_data *drv, + struct nl_msg *msg, int ifindex, int flags, + uint8_t cmd) { - struct nl_msg *msg; - - msg = nlmsg_alloc(); if (!msg) 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, uint8_t cmd) { @@ -4151,6 +4158,7 @@ static int wpa_driver_nl80211_set_acl(void *priv, struct nl_msg *acl; unsigned int i; int ret; + size_t acl_nla_sz, acl_nlmsg_sz, nla_sz, nlmsg_sz; if (!(drv->capa.max_acl_mac_addrs)) 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)", 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) return -ENOMEM; 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 ? NL80211_ACL_POLICY_DENY_UNLESS_LISTED : NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED) ||