On Sun, 2 Apr 2023 23:58:52 +0100 Luca Boccassi <bl...@debian.org> wrote:
> On Sat, 25 Mar 2023 at 00:39, Bernhard Übelacker <bernha...@mailbox.org> > wrote: > > > > Dear Maintainer, > > I tried to find out where exactly the stack smashing takes place. > > And found the ioctl SIOCCHGTUNNEL did write more than the 52 bytes > > allocated in variable old_p, by that overwriting the stack canary. > > > > Kind regards, > > Bernhard > > > > > > (gdb) > > 0x000055555557589f 62 { > > 1: x/i $pc > > => 0x55555557589f <parse_args+31>: mov %fs:0x28,%rax > > (gdb) > > 0x00005555555758a8 62 { > > 1: x/i $pc > > => 0x5555555758a8 <parse_args+40>: mov %rax,0x68(%rsp) > > (gdb) print/x $rax > > $1 = 0xbf9b77d893accd00 > > (gdb) print/x $rsp + 0x68 > > $2 = 0x7fffffffea28 > > > > > > (gdb) > > 0x00007ffff7e575f5 120 in ../sysdeps/unix/syscall-template.S > > 1: x/i $pc > > => 0x7ffff7e575f5 <ioctl+5>: syscall > > 2: /x *(uint64_t*)0x7fffffffea28 = 0xbf9b77d893accd00 > > (gdb) bt > > #0 0x00007ffff7e575f5 in ioctl () at ../sysdeps/unix/syscall-template.S:120 > > #1 0x0000555555578230 in tnl_get_ioctl (basedev=0x7fffffffee8f "gre1", > > p=<optimized out>) at tunnel.c:77 > > #2 0x0000555555576243 in parse_args (argc=9, argv=0x7fffffffec50, > > cmd=35315, p=0x7fffffffea70) at iptunnel.c:181 > > #3 0x00005555555762fb in do_add (cmd=35315, argc=<optimized out>, > > argv=<optimized out>) at iptunnel.c:260 > > #4 0x000055555556258b in do_cmd (argv0=0x7fffffffee81 "tunnel", argc=11, > > argv=0x7fffffffec40) at ip.c:133 > > #5 0x0000555555561fc2 in main (argc=12, argv=0x7fffffffec38) at ip.c:344 > > (gdb) stepi > > 0x00007ffff7e575f7 120 in ../sysdeps/unix/syscall-template.S > > 1: x/i $pc > > => 0x7ffff7e575f7 <ioctl+7>: cmp $0xfffffffffffff001,%rax > > 2: /x *(uint64_t*)0x7fffffffea28 = 0x200000000000000 > > > > (gdb) print &old_p > > $7 = (struct ip_tunnel_parm *) 0x7fffffffe9f0 > > (gdb) print sizeof(old_p) > > $8 = 52 > > (gdb) print/x 0x7fffffffe9f0 + 52 > > $9 = 0x7fffffffea24 > > > > (gdb) list iptunnel.c:181 > > 178 if (cmd == SIOCCHGTUNNEL && count == 0) { > > 179 struct ip_tunnel_parm old_p = {}; > > 180 > > 181 if (tnl_get_ioctl(*argv, &old_p)) > > 182 return -1; > > Hi David and Stephen, > > To reproduce, build iproute2 with -fstack-protector-strong in CFLAGS, and run: > > ip tunnel add gre1 mode ip6gre local 2001:db8::1 remote 2001:db8::2 ttl 255 > ip tunnel change gre1 mode gre local 192.168.0.0 remote 192.168.0.1 ttl 255 > > You'll get: > > *** stack smashing detected ***: terminated > Aborted > > This happens because iproute2 just assumes the tunnel is ipv4, but the > kernel "knows" it's actually ip6gre so when calling the SIOCGETTUNNEL > ioctl it writes back a struct ip6_tnl_parm2 into the struct > ip_tunnel_parm which is smaller, so the stack gets overwritten. Is > there any way to tell from userspace whether a gre is v4 or v6 before > doing an ioctl? The ioctls don't take/return a size parameter as far > as I can see... Is setting IPv4 addresses on an IPv6 tunnel even a valid operation? Assuming the ioctl to get is fixed, is there a reason to allow it? One more reason netlink is better than ioctl.