linux/net/ethtool
Gal Pressman f9dc0f45d2 ethtool: Avoid overflowing userspace buffer on stats query
[ Upstream commit 7b07be1ff1 ]

The ethtool -S command operates across three ioctl calls:
ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and
ETHTOOL_GSTATS for the values.

If the number of stats changes between these calls (e.g., due to device
reconfiguration), userspace's buffer allocation will be incorrect,
potentially leading to buffer overflow.

Drivers are generally expected to maintain stable stat counts, but some
drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making
this scenario possible.

Some drivers try to handle this internally:
- bnad_get_ethtool_stats() returns early in case stats.n_stats is not
  equal to the driver's stats count.
- micrel/ksz884x also makes sure not to write anything beyond
  stats.n_stats and overflow the buffer.

However, both use stats.n_stats which is already assigned with the value
returned from get_sset_count(), hence won't solve the issue described
here.

Change ethtool_get_strings(), ethtool_get_stats(),
ethtool_get_phy_stats() to not return anything in case of a mismatch
between userspace's size and get_sset_size(), to prevent buffer
overflow.
The returned n_stats value will be equal to zero, to reflect that
nothing has been returned.

This could result in one of two cases when using upstream ethtool,
depending on when the size change is detected:
1. When detected in ethtool_get_strings():
    # ethtool -S eth2
    no stats available

2. When detected in get stats, all stats will be reported as zero.

Both cases are presumably transient, and a subsequent ethtool call
should succeed.

Other than the overflow avoidance, these two cases are very evident (no
output/cleared stats), which is arguably better than presenting
incorrect/shifted stats.
I also considered returning an error instead of a "silent" response, but
that seems more destructive towards userspace apps.

Notes:
- This patch does not claim to fix the inherent race, it only makes sure
  that we do not overflow the userspace buffer, and makes for a more
  predictable behavior.

- RTNL lock is held during each ioctl, the race window exists between
  the separate ioctl calls when the lock is released.

- Userspace ethtool always fills stats.n_stats, but it is likely that
  these stats ioctls are implemented in other userspace applications
  which might not fill it. The added code checks that it's not zero,
  to prevent any regressions.

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Signed-off-by: Gal Pressman <gal@nvidia.com>
Link: https://patch.msgid.link/20251208121901.3203692-1-gal@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2026-01-19 13:09:44 +01:00
..
bitset.c ethtool: Fix wrong mod state in case of verbose and no_mask bitset 2024-12-14 19:51:28 +01:00
bitset.h ethtool: add ethnl_parse_bitset() helper 2020-03-12 15:32:32 -07:00
cabletest.c ethtool: link up ethnl_header_policy as a nested policy 2020-10-06 06:25:55 -07:00
channels.c ethtool: fix the check logic of at least one channel for RX/TX 2021-02-28 11:49:07 -08:00
coalesce.c ethtool: extend coalesce setting uAPI with CQE mode 2021-08-24 07:38:29 -07:00
common.c net: sock: extend SO_TIMESTAMPING for PHC binding 2021-07-01 13:08:18 -07:00
common.h net: ethtool: Export helpers for getting EEPROM info 2021-04-11 16:34:56 -07:00
debug.c ethtool: link up ethnl_header_policy as a nested policy 2020-10-06 06:25:55 -07:00
eee.c ethtool: fix incorrect datatype in set_eee ops 2021-04-06 16:42:25 -07:00
eeprom.c ethtool: eeprom: fix null-deref on genl_info in dump 2022-11-03 23:59:14 +09:00
features.c ethtool: netlink: Add missing ethnl_ops_begin/complete 2024-01-25 14:52:54 -08:00
fec.c ethtool: add FEC statistics 2021-04-15 17:08:29 -07:00
ioctl.c ethtool: Avoid overflowing userspace buffer on stats query 2026-01-19 13:09:44 +01:00
linkinfo.c ethtool: link up ethnl_header_policy as a nested policy 2020-10-06 06:25:55 -07:00
linkmodes.c ethtool: reset #lanes when lanes is omitted 2023-04-13 16:48:20 +02:00
linkstate.c ethtool: netlink: do not return SQI value if link is down 2024-07-18 13:07:38 +02:00
Makefile ethtool: add a new command for getting PHC virtual clocks 2021-07-01 13:08:18 -07:00
netlink.c net: ethtool: Don't call .cleanup_data when prepare_data fails 2025-05-02 07:43:52 +02:00
netlink.h ethtool: add two coalesce attributes for CQE mode 2021-08-24 07:38:28 -07:00
pause.c ethtool: fix ethtool msg len calculation for pause stats 2021-11-18 19:17:06 +01:00
phc_vclocks.c ethtool: add a new command for getting PHC virtual clocks 2021-07-01 13:08:18 -07:00
privflags.c ethtool: link up ethnl_header_policy as a nested policy 2020-10-06 06:25:55 -07:00
rings.c ethtool: link up ethnl_header_policy as a nested policy 2020-10-06 06:25:55 -07:00
stats.c ethtool: stats: Fix a copy-paste error 2021-05-19 11:57:33 -07:00
strset.c ethtool: strset: fix message length calculation 2021-06-14 12:14:24 -07:00
tsinfo.c ethtool: link up ethnl_header_policy as a nested policy 2020-10-06 06:25:55 -07:00
tunnels.c ethtool: link up ethnl_header_policy as a nested policy 2020-10-06 06:25:55 -07:00
wol.c ethtool: link up ethnl_header_policy as a nested policy 2020-10-06 06:25:55 -07:00