From 51c96a561f244e25a4a2afc7a48b92b4adf8050d Mon Sep 17 00:00:00 2001 From: Ido Schimmel <idosch@nvidia.com> Date: Sun, 6 Jun 2021 17:24:22 +0300 Subject: ethtool: Fix NULL pointer dereference during module EEPROM dump When get_module_eeprom_by_page() is not implemented by the driver, NULL pointer dereference can occur [1]. Fix by testing if get_module_eeprom_by_page() is implemented instead of get_module_info(). [1] BUG: kernel NULL pointer dereference, address: 0000000000000000 [...] CPU: 0 PID: 251 Comm: ethtool Not tainted 5.13.0-rc3-custom-00940-g3822d0670c9d #989 Call Trace: eeprom_prepare_data+0x101/0x2d0 ethnl_default_doit+0xc2/0x290 genl_family_rcv_msg_doit+0xdc/0x140 genl_rcv_msg+0xd7/0x1d0 netlink_rcv_skb+0x49/0xf0 genl_rcv+0x1f/0x30 netlink_unicast+0x1f6/0x2c0 netlink_sendmsg+0x1f9/0x400 __sys_sendto+0xe1/0x130 __x64_sys_sendto+0x1b/0x20 do_syscall_64+0x3a/0x70 entry_SYSCALL_64_after_hwframe+0x44/0xae Fixes: c97a31f66ebc ("ethtool: wire in generic SFP module access") Signed-off-by: Ido Schimmel <idosch@nvidia.com> Acked-by: Moshe Shemesh <moshe@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/ethtool/eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/ethtool') diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c index 2a6733a6449a..5d38e90895ac 100644 --- a/net/ethtool/eeprom.c +++ b/net/ethtool/eeprom.c @@ -95,7 +95,7 @@ static int get_module_eeprom_by_page(struct net_device *dev, if (dev->sfp_bus) return sfp_get_module_eeprom_by_page(dev->sfp_bus, page_data, extack); - if (ops->get_module_info) + if (ops->get_module_eeprom_by_page) return ops->get_module_eeprom_by_page(dev, page_data, extack); return -EOPNOTSUPP; -- cgit v1.2.3 From 80ec82e3d2c1fab42eeb730aaa7985494a963d3f Mon Sep 17 00:00:00 2001 From: Austin Kim <austindh.kim@gmail.com> Date: Wed, 9 Jun 2021 03:34:25 +0100 Subject: net: ethtool: clear heap allocations for ethtool function Several ethtool functions leave heap uncleared (potentially) by drivers. This will leave the unused portion of heap unchanged and might copy the full contents back to userspace. Signed-off-by: Austin Kim <austindh.kim@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/ethtool/ioctl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'net/ethtool') diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 3fa7a394eabf..baa5d10043cb 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -1421,7 +1421,7 @@ static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr, if (eeprom.offset + eeprom.len > total_len) return -EINVAL; - data = kmalloc(PAGE_SIZE, GFP_USER); + data = kzalloc(PAGE_SIZE, GFP_USER); if (!data) return -ENOMEM; @@ -1486,7 +1486,7 @@ static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) return -EINVAL; - data = kmalloc(PAGE_SIZE, GFP_USER); + data = kzalloc(PAGE_SIZE, GFP_USER); if (!data) return -ENOMEM; @@ -1765,7 +1765,7 @@ static int ethtool_self_test(struct net_device *dev, char __user *useraddr) return -EFAULT; test.len = test_len; - data = kmalloc_array(test_len, sizeof(u64), GFP_USER); + data = kcalloc(test_len, sizeof(u64), GFP_USER); if (!data) return -ENOMEM; @@ -2293,7 +2293,7 @@ static int ethtool_get_tunable(struct net_device *dev, void __user *useraddr) ret = ethtool_tunable_valid(&tuna); if (ret) return ret; - data = kmalloc(tuna.len, GFP_USER); + data = kzalloc(tuna.len, GFP_USER); if (!data) return -ENOMEM; ret = ops->get_tunable(dev, &tuna, data); @@ -2485,7 +2485,7 @@ static int get_phy_tunable(struct net_device *dev, void __user *useraddr) ret = ethtool_phy_tunable_valid(&tuna); if (ret) return ret; - data = kmalloc(tuna.len, GFP_USER); + data = kzalloc(tuna.len, GFP_USER); if (!data) return -ENOMEM; if (phy_drv_tunable) { -- cgit v1.2.3 From e175aef902697826d344ce3a12189329848fe898 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski <kuba@kernel.org> Date: Fri, 11 Jun 2021 18:49:48 -0700 Subject: ethtool: strset: fix message length calculation Outer nest for ETHTOOL_A_STRSET_STRINGSETS is not accounted for. This may result in ETHTOOL_MSG_STRSET_GET producing a warning like: calculated message payload length (684) not sufficient WARNING: CPU: 0 PID: 30967 at net/ethtool/netlink.c:369 ethnl_default_doit+0x87a/0xa20 and a splat. As usually with such warnings three conditions must be met for the warning to trigger: - there must be no skb size rounding up (e.g. reply_size of 684); - string set must be per-device (so that the header gets populated); - the device name must be at least 12 characters long. all in all with current user space it looks like reading priv flags is the only place this could potentially happen. Or with syzbot :) Reported-by: syzbot+59aa77b92d06cd5a54f2@syzkaller.appspotmail.com Fixes: 71921690f974 ("ethtool: provide string sets with STRSET_GET request") Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/ethtool/strset.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net/ethtool') diff --git a/net/ethtool/strset.c b/net/ethtool/strset.c index b3029fff715d..2d51b7ab4dc5 100644 --- a/net/ethtool/strset.c +++ b/net/ethtool/strset.c @@ -353,6 +353,8 @@ static int strset_reply_size(const struct ethnl_req_info *req_base, int len = 0; int ret; + len += nla_total_size(0); /* ETHTOOL_A_STRSET_STRINGSETS */ + for (i = 0; i < ETH_SS_COUNT; i++) { const struct strset_info *set_info = &data->sets[i]; -- cgit v1.2.3