Skip to content

Commit 8866df9

Browse files
committed
netfilter: nfnetlink_cttimeout: pass default timeout policy to obj_to_nlattr
Otherwise, we hit a NULL pointer deference since handlers always assume default timeout policy is passed. netlink: 24 bytes leftover after parsing attributes in process `syz-executor2'. kasan: CONFIG_KASAN_INLINE enabled kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 9575 Comm: syz-executor1 Not tainted 4.19.0+ torvalds#312 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:icmp_timeout_obj_to_nlattr+0x77/0x170 net/netfilter/nf_conntrack_proto_icmp.c:297 Fixes: c779e84 ("netfilter: conntrack: remove get_timeout() indirection") Reported-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent a95a777 commit 8866df9

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

net/netfilter/nfnetlink_cttimeout.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,8 @@ static int cttimeout_default_set(struct net *net, struct sock *ctnl,
382382
static int
383383
cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
384384
u32 seq, u32 type, int event, u16 l3num,
385-
const struct nf_conntrack_l4proto *l4proto)
385+
const struct nf_conntrack_l4proto *l4proto,
386+
const unsigned int *timeouts)
386387
{
387388
struct nlmsghdr *nlh;
388389
struct nfgenmsg *nfmsg;
@@ -408,7 +409,7 @@ cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
408409
if (!nest_parms)
409410
goto nla_put_failure;
410411

411-
ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, NULL);
412+
ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
412413
if (ret < 0)
413414
goto nla_put_failure;
414415

@@ -430,6 +431,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
430431
struct netlink_ext_ack *extack)
431432
{
432433
const struct nf_conntrack_l4proto *l4proto;
434+
unsigned int *timeouts = NULL;
433435
struct sk_buff *skb2;
434436
int ret, err;
435437
__u16 l3num;
@@ -442,12 +444,44 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
442444
l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
443445
l4proto = nf_ct_l4proto_find_get(l4num);
444446

445-
/* This protocol is not supported, skip. */
446-
if (l4proto->l4proto != l4num) {
447-
err = -EOPNOTSUPP;
447+
err = -EOPNOTSUPP;
448+
if (l4proto->l4proto != l4num)
448449
goto err;
450+
451+
switch (l4proto->l4proto) {
452+
case IPPROTO_ICMP:
453+
timeouts = &nf_icmp_pernet(net)->timeout;
454+
break;
455+
case IPPROTO_TCP:
456+
timeouts = nf_tcp_pernet(net)->timeouts;
457+
break;
458+
case IPPROTO_UDP:
459+
timeouts = nf_udp_pernet(net)->timeouts;
460+
break;
461+
case IPPROTO_DCCP:
462+
#ifdef CONFIG_NF_CT_PROTO_DCCP
463+
timeouts = nf_dccp_pernet(net)->dccp_timeout;
464+
#endif
465+
break;
466+
case IPPROTO_ICMPV6:
467+
timeouts = &nf_icmpv6_pernet(net)->timeout;
468+
break;
469+
case IPPROTO_SCTP:
470+
#ifdef CONFIG_NF_CT_PROTO_SCTP
471+
timeouts = nf_sctp_pernet(net)->timeouts;
472+
#endif
473+
break;
474+
case 255:
475+
timeouts = &nf_generic_pernet(net)->timeout;
476+
break;
477+
default:
478+
WARN_ON_ONCE(1);
479+
break;
449480
}
450481

482+
if (!timeouts)
483+
goto err;
484+
451485
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
452486
if (skb2 == NULL) {
453487
err = -ENOMEM;
@@ -458,8 +492,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
458492
nlh->nlmsg_seq,
459493
NFNL_MSG_TYPE(nlh->nlmsg_type),
460494
IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
461-
l3num,
462-
l4proto);
495+
l3num, l4proto, timeouts);
463496
if (ret <= 0) {
464497
kfree_skb(skb2);
465498
err = -ENOMEM;

0 commit comments

Comments
 (0)