mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
netpoll: pass buffer size to egress_dev() to avoid MAC truncation
egress_dev() formats np->dev_mac via snprintf() but receives buf as
a bare char *, so it cannot derive the buffer size from the pointer. The
size argument was hardcoded to MAC_ADDR_STR_LEN (3 * ETH_ALEN - 1 = 17),
which is silly wrong in two ways:
1) misleading kernel log output on the MAC-selected target path
(np->dev_name[0] == '\0'); for example "aa:bb:cc:dd:ee:ff doesn't
exist, aborting" was logged as "aa:bb:cc:dd:ee:f doesn't exist,
aborting".
2) the second argument of snprintf is the size of the buffer, not the
size of what you want to write.
Add a bufsz parameter to egress_dev() and pass sizeof(buf) from each
caller, matching the standard snprintf() idiom and removing the
hardcoded size from the helper.
Every caller already declares "char buf[MAC_ADDR_STR_LEN + 1]" so the
formatted MAC continues to fit.
Tested by booting with
netconsole=6665@/aa:bb:cc:dd:ee:ff,6666@10.0.0.1/00:11:22:33:44:55
on a kernel without a matching device. Pre-fix dmesg shows
"aa:bb:cc:dd:ee:f doesn't exist, aborting"; post-fix shows the full
"aa:bb:cc:dd:ee:ff doesn't exist, aborting".
Fixes: f8a10bed32 ("netconsole: allow selection of egress interface via MAC address")
Cc: stable@vger.kernel.org
Signed-off-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260501-netpoll_snprintf_fix-v1-1-84b0566e6597@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
d82ba05263
commit
76b93a8107
|
|
@ -608,14 +608,16 @@ EXPORT_SYMBOL_GPL(__netpoll_setup);
|
|||
/*
|
||||
* Returns a pointer to a string representation of the identifier used
|
||||
* to select the egress interface for the given netpoll instance. buf
|
||||
* must be a buffer of length at least MAC_ADDR_STR_LEN + 1.
|
||||
* is used to format np->dev_mac when np->dev_name is empty; bufsz must
|
||||
* be at least MAC_ADDR_STR_LEN + 1 to fit the formatted MAC address
|
||||
* and its NUL terminator.
|
||||
*/
|
||||
static char *egress_dev(struct netpoll *np, char *buf)
|
||||
static char *egress_dev(struct netpoll *np, char *buf, size_t bufsz)
|
||||
{
|
||||
if (np->dev_name[0])
|
||||
return np->dev_name;
|
||||
|
||||
snprintf(buf, MAC_ADDR_STR_LEN, "%pM", np->dev_mac);
|
||||
snprintf(buf, bufsz, "%pM", np->dev_mac);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
@ -645,7 +647,7 @@ static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev)
|
|||
|
||||
if (!IS_ENABLED(CONFIG_IPV6)) {
|
||||
np_err(np, "IPv6 is not supported %s, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
egress_dev(np, buf, sizeof(buf)));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -667,7 +669,7 @@ static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev)
|
|||
}
|
||||
if (err) {
|
||||
np_err(np, "no IPv6 address for %s, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
egress_dev(np, buf, sizeof(buf)));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -687,14 +689,14 @@ static int netpoll_take_ipv4(struct netpoll *np, struct net_device *ndev)
|
|||
in_dev = __in_dev_get_rtnl(ndev);
|
||||
if (!in_dev) {
|
||||
np_err(np, "no IP address for %s, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
egress_dev(np, buf, sizeof(buf)));
|
||||
return -EDESTADDRREQ;
|
||||
}
|
||||
|
||||
ifa = rtnl_dereference(in_dev->ifa_list);
|
||||
if (!ifa) {
|
||||
np_err(np, "no IP address for %s, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
egress_dev(np, buf, sizeof(buf)));
|
||||
return -EDESTADDRREQ;
|
||||
}
|
||||
|
||||
|
|
@ -736,7 +738,8 @@ int netpoll_setup(struct netpoll *np)
|
|||
ndev = dev_getbyhwaddr(net, ARPHRD_ETHER, np->dev_mac);
|
||||
|
||||
if (!ndev) {
|
||||
np_err(np, "%s doesn't exist, aborting\n", egress_dev(np, buf));
|
||||
np_err(np, "%s doesn't exist, aborting\n",
|
||||
egress_dev(np, buf, sizeof(buf)));
|
||||
err = -ENODEV;
|
||||
goto unlock;
|
||||
}
|
||||
|
|
@ -744,14 +747,14 @@ int netpoll_setup(struct netpoll *np)
|
|||
|
||||
if (netdev_master_upper_dev_get(ndev)) {
|
||||
np_err(np, "%s is a slave device, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
egress_dev(np, buf, sizeof(buf)));
|
||||
err = -EBUSY;
|
||||
goto put;
|
||||
}
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
np_info(np, "device %s not up yet, forcing it\n",
|
||||
egress_dev(np, buf));
|
||||
egress_dev(np, buf, sizeof(buf)));
|
||||
|
||||
err = dev_open(ndev, NULL);
|
||||
if (err) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user