Skip to content

Commit fd3d9ed

Browse files
q2venNipaLocal
authored and
NipaLocal
committed
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 kernel-patches#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: fa76c16 ("ipv6: Move some validation from ip6_route_info_create() to rtm_to_fib6_config().") Reported-by: syzkaller <[email protected]> Reported-by: Yi Lai <[email protected]> Closes: https://lore.kernel.org/netdev/aBAcKDEFoN%2FLntBF@ly-workstation/ Signed-off-by: Kuniyuki Iwashima <[email protected]> Reviewed-by: David Ahern <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent 9994f8a commit fd3d9ed

File tree

1 file changed

+55
-42
lines changed

1 file changed

+55
-42
lines changed

net/ipv6/route.c

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4503,6 +4503,53 @@ void rt6_purge_dflt_routers(struct net *net)
45034503
rcu_read_unlock();
45044504
}
45054505

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+
45064553
static void rtmsg_to_fib6_config(struct net *net,
45074554
struct in6_rtmsg *rtmsg,
45084555
struct fib6_config *cfg)
@@ -4540,6 +4587,10 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, struct in6_rtmsg *rtmsg)
45404587

45414588
switch (cmd) {
45424589
case SIOCADDRT:
4590+
err = fib6_config_validate(&cfg, NULL);
4591+
if (err)
4592+
break;
4593+
45434594
/* Only do the default setting of fc_metric in route adding */
45444595
if (cfg.fc_metric == 0)
45454596
cfg.fc_metric = IP6_RT_PRIO_USER;
@@ -5274,48 +5325,6 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
52745325
}
52755326
}
52765327

5277-
if (newroute) {
5278-
/* RTF_PCPU is an internal flag; can not be set by userspace */
5279-
if (cfg->fc_flags & RTF_PCPU) {
5280-
NL_SET_ERR_MSG(extack, "Userspace can not set RTF_PCPU");
5281-
goto errout;
5282-
}
5283-
5284-
/* RTF_CACHE is an internal flag; can not be set by userspace */
5285-
if (cfg->fc_flags & RTF_CACHE) {
5286-
NL_SET_ERR_MSG(extack, "Userspace can not set RTF_CACHE");
5287-
goto errout;
5288-
}
5289-
5290-
if (cfg->fc_type > RTN_MAX) {
5291-
NL_SET_ERR_MSG(extack, "Invalid route type");
5292-
goto errout;
5293-
}
5294-
5295-
if (cfg->fc_dst_len > 128) {
5296-
NL_SET_ERR_MSG(extack, "Invalid prefix length");
5297-
goto errout;
5298-
}
5299-
5300-
#ifdef CONFIG_IPV6_SUBTREES
5301-
if (cfg->fc_src_len > 128) {
5302-
NL_SET_ERR_MSG(extack, "Invalid source address length");
5303-
goto errout;
5304-
}
5305-
5306-
if (cfg->fc_nh_id && cfg->fc_src_len) {
5307-
NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing");
5308-
goto errout;
5309-
}
5310-
#else
5311-
if (cfg->fc_src_len) {
5312-
NL_SET_ERR_MSG(extack,
5313-
"Specifying source address requires IPV6_SUBTREES to be enabled");
5314-
goto errout;
5315-
}
5316-
#endif
5317-
}
5318-
53195328
err = 0;
53205329
errout:
53215330
return err;
@@ -5710,6 +5719,10 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
57105719
if (err < 0)
57115720
return err;
57125721

5722+
err = fib6_config_validate(&cfg, extack);
5723+
if (err)
5724+
return err;
5725+
57135726
if (cfg.fc_metric == 0)
57145727
cfg.fc_metric = IP6_RT_PRIO_USER;
57155728

0 commit comments

Comments
 (0)