Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ipv6: Restore fib6_config validation for SIOCADDRT.

syzkaller reported out-of-bounds read in ipv6_addr_prefix(),
where the prefix length was over 128.

The cited commit accidentally removed some fib6_config
validation from the ioctl path.

Let's restore the validation.

[0]:
BUG: KASAN: slab-out-of-bounds in ip6_route_info_create (./include/net/ipv6.h:616 net/ipv6/route.c:3814)
Read of size 1 at addr ff11000138020ad4 by task repro/261

CPU: 3 UID: 0 PID: 261 Comm: repro Not tainted 6.15.0-rc3-00614-g0d15a26b247d #87 PREEMPT(voluntary)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl (lib/dump_stack.c:123)
print_report (mm/kasan/report.c:409 mm/kasan/report.c:521)
kasan_report (mm/kasan/report.c:636)
ip6_route_info_create (./include/net/ipv6.h:616 net/ipv6/route.c:3814)
ip6_route_add (net/ipv6/route.c:3902)
ipv6_route_ioctl (net/ipv6/route.c:4523)
inet6_ioctl (net/ipv6/af_inet6.c:577)
sock_do_ioctl (net/socket.c:1190)
sock_ioctl (net/socket.c:1314)
__x64_sys_ioctl (fs/ioctl.c:51 fs/ioctl.c:906 fs/ioctl.c:892 fs/ioctl.c:892)
do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
RIP: 0033:0x7f518fb2de5d
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48
RSP: 002b:00007fff14f38d18 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f518fb2de5d
RDX: 00000000200015c0 RSI: 000000000000890b RDI: 0000000000000003
RBP: 00007fff14f38d30 R08: 0000000000000800 R09: 0000000000000800
R10: 0000000000000000 R11: 0000000000000202 R12: 00007fff14f38e48
R13: 0000000000401136 R14: 0000000000403df0 R15: 00007f518fd3c000
</TASK>

Fixes: fa76c1674f2e ("ipv6: Move some validation from ip6_route_info_create() to rtm_to_fib6_config().")
Reported-by: syzkaller <syzkaller@googlegroups.com>
Reported-by: Yi Lai <yi1.lai@linux.intel.com>
Closes: https://lore.kernel.org/netdev/aBAcKDEFoN%2FLntBF@ly-workstation/
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250501005335.53683-1-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
586ceac9 a2f6476e

+55 -42
+55 -42
net/ipv6/route.c
··· 4503 4503 rcu_read_unlock(); 4504 4504 } 4505 4505 4506 + static int fib6_config_validate(struct fib6_config *cfg, 4507 + struct netlink_ext_ack *extack) 4508 + { 4509 + /* RTF_PCPU is an internal flag; can not be set by userspace */ 4510 + if (cfg->fc_flags & RTF_PCPU) { 4511 + NL_SET_ERR_MSG(extack, "Userspace can not set RTF_PCPU"); 4512 + goto errout; 4513 + } 4514 + 4515 + /* RTF_CACHE is an internal flag; can not be set by userspace */ 4516 + if (cfg->fc_flags & RTF_CACHE) { 4517 + NL_SET_ERR_MSG(extack, "Userspace can not set RTF_CACHE"); 4518 + goto errout; 4519 + } 4520 + 4521 + if (cfg->fc_type > RTN_MAX) { 4522 + NL_SET_ERR_MSG(extack, "Invalid route type"); 4523 + goto errout; 4524 + } 4525 + 4526 + if (cfg->fc_dst_len > 128) { 4527 + NL_SET_ERR_MSG(extack, "Invalid prefix length"); 4528 + goto errout; 4529 + } 4530 + 4531 + #ifdef CONFIG_IPV6_SUBTREES 4532 + if (cfg->fc_src_len > 128) { 4533 + NL_SET_ERR_MSG(extack, "Invalid source address length"); 4534 + goto errout; 4535 + } 4536 + 4537 + if (cfg->fc_nh_id && cfg->fc_src_len) { 4538 + NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing"); 4539 + goto errout; 4540 + } 4541 + #else 4542 + if (cfg->fc_src_len) { 4543 + NL_SET_ERR_MSG(extack, 4544 + "Specifying source address requires IPV6_SUBTREES to be enabled"); 4545 + goto errout; 4546 + } 4547 + #endif 4548 + return 0; 4549 + errout: 4550 + return -EINVAL; 4551 + } 4552 + 4506 4553 static void rtmsg_to_fib6_config(struct net *net, 4507 4554 struct in6_rtmsg *rtmsg, 4508 4555 struct fib6_config *cfg) ··· 4587 4540 4588 4541 switch (cmd) { 4589 4542 case SIOCADDRT: 4543 + err = fib6_config_validate(&cfg, NULL); 4544 + if (err) 4545 + break; 4546 + 4590 4547 /* Only do the default setting of fc_metric in route adding */ 4591 4548 if (cfg.fc_metric == 0) 4592 4549 cfg.fc_metric = IP6_RT_PRIO_USER; ··· 5325 5274 } 5326 5275 } 5327 5276 5328 - if (newroute) { 5329 - /* RTF_PCPU is an internal flag; can not be set by userspace */ 5330 - if (cfg->fc_flags & RTF_PCPU) { 5331 - NL_SET_ERR_MSG(extack, "Userspace can not set RTF_PCPU"); 5332 - goto errout; 5333 - } 5334 - 5335 - /* RTF_CACHE is an internal flag; can not be set by userspace */ 5336 - if (cfg->fc_flags & RTF_CACHE) { 5337 - NL_SET_ERR_MSG(extack, "Userspace can not set RTF_CACHE"); 5338 - goto errout; 5339 - } 5340 - 5341 - if (cfg->fc_type > RTN_MAX) { 5342 - NL_SET_ERR_MSG(extack, "Invalid route type"); 5343 - goto errout; 5344 - } 5345 - 5346 - if (cfg->fc_dst_len > 128) { 5347 - NL_SET_ERR_MSG(extack, "Invalid prefix length"); 5348 - goto errout; 5349 - } 5350 - 5351 - #ifdef CONFIG_IPV6_SUBTREES 5352 - if (cfg->fc_src_len > 128) { 5353 - NL_SET_ERR_MSG(extack, "Invalid source address length"); 5354 - goto errout; 5355 - } 5356 - 5357 - if (cfg->fc_nh_id && cfg->fc_src_len) { 5358 - NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing"); 5359 - goto errout; 5360 - } 5361 - #else 5362 - if (cfg->fc_src_len) { 5363 - NL_SET_ERR_MSG(extack, 5364 - "Specifying source address requires IPV6_SUBTREES to be enabled"); 5365 - goto errout; 5366 - } 5367 - #endif 5368 - } 5369 - 5370 5277 err = 0; 5371 5278 errout: 5372 5279 return err; ··· 5717 5708 5718 5709 err = rtm_to_fib6_config(skb, nlh, &cfg, extack); 5719 5710 if (err < 0) 5711 + return err; 5712 + 5713 + err = fib6_config_validate(&cfg, extack); 5714 + if (err) 5720 5715 return err; 5721 5716 5722 5717 if (cfg.fc_metric == 0)