| From 7ea862048317aa76d0f22334202779a25530980c Mon Sep 17 00:00:00 2001 |
| From: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi> |
| Date: Fri, 10 Apr 2020 15:32:57 +0300 |
| Subject: mac80211_hwsim: Use kstrndup() in place of kasprintf() |
| |
| From: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi> |
| |
| commit 7ea862048317aa76d0f22334202779a25530980c upstream. |
| |
| syzbot reports a warning: |
| |
| precision 33020 too large |
| WARNING: CPU: 0 PID: 9618 at lib/vsprintf.c:2471 set_precision+0x150/0x180 lib/vsprintf.c:2471 |
| vsnprintf+0xa7b/0x19a0 lib/vsprintf.c:2547 |
| kvasprintf+0xb2/0x170 lib/kasprintf.c:22 |
| kasprintf+0xbb/0xf0 lib/kasprintf.c:59 |
| hwsim_del_radio_nl+0x63a/0x7e0 drivers/net/wireless/mac80211_hwsim.c:3625 |
| genl_family_rcv_msg_doit net/netlink/genetlink.c:672 [inline] |
| ... |
| entry_SYSCALL_64_after_hwframe+0x49/0xbe |
| |
| Thus it seems that kasprintf() with "%.*s" format can not be used for |
| duplicating a string with arbitrary length. Replace it with kstrndup(). |
| |
| Note that later this string is limited to NL80211_WIPHY_NAME_MAXLEN == 64, |
| but the code is simpler this way. |
| |
| Reported-by: syzbot+6693adf1698864d21734@syzkaller.appspotmail.com |
| Reported-by: syzbot+a4aee3f42d7584d76761@syzkaller.appspotmail.com |
| Cc: stable@kernel.org |
| Signed-off-by: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi> |
| Link: https://lore.kernel.org/r/20200410123257.14559-1-tuomas.tynkkynen@iki.fi |
| [johannes: add note about length limit] |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/wireless/mac80211_hwsim.c | 12 ++++++------ |
| 1 file changed, 6 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/net/wireless/mac80211_hwsim.c |
| +++ b/drivers/net/wireless/mac80211_hwsim.c |
| @@ -3575,9 +3575,9 @@ static int hwsim_new_radio_nl(struct sk_ |
| } |
| |
| if (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])); |
| + hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]), |
| + nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), |
| + GFP_KERNEL); |
| if (!hwname) |
| return -ENOMEM; |
| param.hwname = hwname; |
| @@ -3597,9 +3597,9 @@ static int hwsim_del_radio_nl(struct sk_ |
| if (info->attrs[HWSIM_ATTR_RADIO_ID]) { |
| idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); |
| } else if (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])); |
| + hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]), |
| + nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), |
| + GFP_KERNEL); |
| if (!hwname) |
| return -ENOMEM; |
| } else |