mac80211_hwsim: check HWSIM_ATTR_RADIO_NAME length

[ Upstream commit ff4dd73dd2b4806419f8ff65cbce11d5019548d0 ]

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>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Johannes Berg 2017-02-27 17:15:28 +01:00 committed by Greg Kroah-Hartman
parent 4a464dacc2
commit 3e8c1a04d3

View file

@ -2884,6 +2884,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];
@ -2897,8 +2898,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;
@ -2926,11 +2933,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);
@ -2939,7 +2950,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;
} }
@ -2947,10 +2959,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;
} }