aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-11-01 19:14:00 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2018-11-03 08:28:03 -0400
commit8866df9264a34e675b4ee8a151db819b87cce2d3 (patch)
tree9d7f7ce50406f63272a4c6603334578db097b569
parenta95a7774d51e13f9cf4b7285666829b68852f07a (diff)
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+ #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: c779e849608a ("netfilter: conntrack: remove get_timeout() indirection") Reported-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index e7a50af1b3d6..a518eb162344 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -382,7 +382,8 @@ err:
382static int 382static int
383cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid, 383cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
384 u32 seq, u32 type, int event, u16 l3num, 384 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)
386{ 387{
387 struct nlmsghdr *nlh; 388 struct nlmsghdr *nlh;
388 struct nfgenmsg *nfmsg; 389 struct nfgenmsg *nfmsg;
@@ -408,7 +409,7 @@ cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
408 if (!nest_parms) 409 if (!nest_parms)
409 goto nla_put_failure; 410 goto nla_put_failure;
410 411
411 ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, NULL); 412 ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
412 if (ret < 0) 413 if (ret < 0)
413 goto nla_put_failure; 414 goto nla_put_failure;
414 415
@@ -430,6 +431,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
430 struct netlink_ext_ack *extack) 431 struct netlink_ext_ack *extack)
431{ 432{
432 const struct nf_conntrack_l4proto *l4proto; 433 const struct nf_conntrack_l4proto *l4proto;
434 unsigned int *timeouts = NULL;
433 struct sk_buff *skb2; 435 struct sk_buff *skb2;
434 int ret, err; 436 int ret, err;
435 __u16 l3num; 437 __u16 l3num;
@@ -442,12 +444,44 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
442 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]); 444 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
443 l4proto = nf_ct_l4proto_find_get(l4num); 445 l4proto = nf_ct_l4proto_find_get(l4num);
444 446
445 /* This protocol is not supported, skip. */ 447 err = -EOPNOTSUPP;
446 if (l4proto->l4proto != l4num) { 448 if (l4proto->l4proto != l4num)
447 err = -EOPNOTSUPP;
448 goto err; 449 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;
449 } 480 }
450 481
482 if (!timeouts)
483 goto err;
484
451 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 485 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
452 if (skb2 == NULL) { 486 if (skb2 == NULL) {
453 err = -ENOMEM; 487 err = -ENOMEM;
@@ -458,8 +492,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
458 nlh->nlmsg_seq, 492 nlh->nlmsg_seq,
459 NFNL_MSG_TYPE(nlh->nlmsg_type), 493 NFNL_MSG_TYPE(nlh->nlmsg_type),
460 IPCTNL_MSG_TIMEOUT_DEFAULT_SET, 494 IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
461 l3num, 495 l3num, l4proto, timeouts);
462 l4proto);
463 if (ret <= 0) { 496 if (ret <= 0) {
464 kfree_skb(skb2); 497 kfree_skb(skb2);
465 err = -ENOMEM; 498 err = -ENOMEM;