* [PATCH iproute] iptunnel: use worst case buffer for tunnel ioctls
@ 2026-10-20 15:46 Stephen Hemminger
2026-10-20 19:05 ` Jakub Kicinski
0 siblings, 1 reply; 2+ messages in thread
From: Stephen Hemminger @ 2026-10-20 15:46 UTC (permalink / raw)
To: netdev; +Cc: Stephen Hemminger, Claude
The tunnel ioctls are device private, so the kernel fills in
whatever parameter structure the device uses, and that can be
the larger IPv6 struct ip6_tnl_parm2 when an IPv4 tunnel was expected.
Ust a worst case union similar to commit 8cc2eac6 ("iptunnel: detect
protocol mismatch on tunnel change") already uses on the change
path for add, del and show as well.
Reported-by: Anthropic OSS scanner
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iptunnel.c | 50 +++++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/ip/iptunnel.c b/ip/iptunnel.c
index b6da1459..8d590704 100644
--- a/ip/iptunnel.c
+++ b/ip/iptunnel.c
@@ -24,6 +24,18 @@
#include "ip_common.h"
#include "tunnel.h"
+/*
+ * The tunnel ioctls are device private: the driver of whatever device
+ * owns the name decides how many bytes it copies to ifru_data. The
+ * name may belong to an IPv6 tunnel (user error, or a rename between
+ * the link dump and the ioctl), so always give the kernel a buffer
+ * large enough for any tunnel parameter block.
+ */
+union ip_tnl_parm {
+ struct ip_tunnel_parm ip_tnl;
+ struct ip6_tnl_parm2 ip6_tnl;
+};
+
static void usage(void) __attribute__((noreturn));
static void usage(void)
@@ -173,10 +185,7 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
if (get_ifname(p->name, *argv))
invarg("\"name\" not a valid ifname", *argv);
if (cmd == SIOCCHGTUNNEL && count == 0) {
- union {
- struct ip_tunnel_parm ip_tnl;
- struct ip6_tnl_parm2 ip6_tnl;
- } old_p = {};
+ union ip_tnl_parm old_p = {};
if (tnl_get_ioctl(*argv, &old_p))
return -1;
@@ -260,35 +269,37 @@ static const char *tnl_defname(const struct ip_tunnel_parm *p)
static int do_add(int cmd, int argc, char **argv)
{
- struct ip_tunnel_parm p;
+ union ip_tnl_parm u = {};
+ struct ip_tunnel_parm *p = &u.ip_tnl;
const char *basedev;
- if (parse_args(argc, argv, cmd, &p) < 0)
+ if (parse_args(argc, argv, cmd, p) < 0)
return -1;
- if (p.iph.ttl && p.iph.frag_off == 0) {
+ if (p->iph.ttl && p->iph.frag_off == 0) {
fprintf(stderr, "ttl != 0 and nopmtudisc are incompatible\n");
return -1;
}
- basedev = tnl_defname(&p);
+ basedev = tnl_defname(p);
if (!basedev) {
fprintf(stderr,
"cannot determine tunnel mode (ipip, gre, vti or sit)\n");
return -1;
}
- return tnl_add_ioctl(cmd, basedev, p.name, &p);
+ return tnl_add_ioctl(cmd, basedev, p->name, &u);
}
static int do_del(int argc, char **argv)
{
- struct ip_tunnel_parm p;
+ union ip_tnl_parm u = {};
+ struct ip_tunnel_parm *p = &u.ip_tnl;
- if (parse_args(argc, argv, SIOCDELTUNNEL, &p) < 0)
+ if (parse_args(argc, argv, SIOCDELTUNNEL, p) < 0)
return -1;
- return tnl_del_ioctl(tnl_defname(&p) ? : p.name, p.name, &p);
+ return tnl_del_ioctl(tnl_defname(p) ? : p->name, p->name, &u);
}
static void print_tunnel(const void *t)
@@ -410,17 +421,18 @@ static bool ip_tunnel_parm_match(const struct tnl_print_nlmsg_info *info)
static int do_show(int argc, char **argv)
{
- struct ip_tunnel_parm p, p1;
+ union ip_tnl_parm u = {}, u1 = {};
+ struct ip_tunnel_parm *p = &u.ip_tnl;
const char *basedev;
- if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0)
+ if (parse_args(argc, argv, SIOCGETTUNNEL, p) < 0)
return -1;
- basedev = tnl_defname(&p);
+ basedev = tnl_defname(p);
if (!basedev) {
struct tnl_print_nlmsg_info info = {
- .p1 = &p,
- .p2 = &p1,
+ .p1 = p,
+ .p2 = &u1,
.init = ip_tunnel_parm_initialize,
.match = ip_tunnel_parm_match,
.print = print_tunnel,
@@ -429,10 +441,10 @@ static int do_show(int argc, char **argv)
return do_tunnels_list(&info);
}
- if (tnl_get_ioctl(p.name[0] ? p.name : basedev, &p))
+ if (tnl_get_ioctl(p->name[0] ? p->name : basedev, &u))
return -1;
- print_tunnel(&p);
+ print_tunnel(p);
fputc('\n', stdout);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH iproute] iptunnel: use worst case buffer for tunnel ioctls
2026-10-20 15:46 [PATCH iproute] iptunnel: use worst case buffer for tunnel ioctls Stephen Hemminger
@ 2026-10-20 19:05 ` Jakub Kicinski
0 siblings, 0 replies; 2+ messages in thread
From: Jakub Kicinski @ 2026-10-20 19:05 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Claude
On Tue, 20 Oct 2026 08:46:35 -0700 Stephen Hemminger wrote:
> Subject: [PATCH iproute] iptunnel: use worst case buffer for tunnel ioctls
Please tell your bot that the correct tag is iproute2 not iproute
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-20 19:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-20 15:46 [PATCH iproute] iptunnel: use worst case buffer for tunnel ioctls Stephen Hemminger
2026-10-20 19:05 ` Jakub Kicinski
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.