2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-21 03:33:59 +08:00

mac80211_hwsim: check HWSIM_ATTR_RADIO_NAME length

Unfortunately, the nla policy was defined to have HWSIM_ATTR_RADIO_NAME
as an NLA_STRING, rather than NLA_NUL_STRING, so we can't use it as a
NUL-terminated string in the kernel.

Rather than break the API, kasprintf() the string to a new buffer to
guarantee NUL termination.

Reported-by: Andrew Zaborowski <andrew.zaborowski@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2017-02-27 17:15:28 +01:00
parent 09e0a2fe10
commit ff4dd73dd2

View File

@ -3056,6 +3056,7 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2,
static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
{ {
struct hwsim_new_radio_params param = { 0 }; struct hwsim_new_radio_params param = { 0 };
const char *hwname = NULL;
param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE];
@ -3069,8 +3070,14 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
if (info->attrs[HWSIM_ATTR_NO_VIF]) if (info->attrs[HWSIM_ATTR_NO_VIF])
param.no_vif = true; param.no_vif = true;
if (info->attrs[HWSIM_ATTR_RADIO_NAME]) if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
param.hwname = nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); hwname = kasprintf(GFP_KERNEL, "%.*s",
nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
(char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]));
if (!hwname)
return -ENOMEM;
param.hwname = hwname;
}
if (info->attrs[HWSIM_ATTR_USE_CHANCTX]) if (info->attrs[HWSIM_ATTR_USE_CHANCTX])
param.use_chanctx = true; param.use_chanctx = true;
@ -3098,11 +3105,15 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
s64 idx = -1; s64 idx = -1;
const char *hwname = NULL; const char *hwname = NULL;
if (info->attrs[HWSIM_ATTR_RADIO_ID]) if (info->attrs[HWSIM_ATTR_RADIO_ID]) {
idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]);
else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) } else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
hwname = (void *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); hwname = kasprintf(GFP_KERNEL, "%.*s",
else nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
(char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]));
if (!hwname)
return -ENOMEM;
} else
return -EINVAL; return -EINVAL;
spin_lock_bh(&hwsim_radio_lock); spin_lock_bh(&hwsim_radio_lock);
@ -3111,7 +3122,8 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
if (data->idx != idx) if (data->idx != idx)
continue; continue;
} else { } else {
if (strcmp(hwname, wiphy_name(data->hw->wiphy))) if (!hwname ||
strcmp(hwname, wiphy_name(data->hw->wiphy)))
continue; continue;
} }
@ -3122,10 +3134,12 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
spin_unlock_bh(&hwsim_radio_lock); spin_unlock_bh(&hwsim_radio_lock);
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
info); info);
kfree(hwname);
return 0; return 0;
} }
spin_unlock_bh(&hwsim_radio_lock); spin_unlock_bh(&hwsim_radio_lock);
kfree(hwname);
return -ENODEV; return -ENODEV;
} }