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

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Pablo Neira Ayuso says:

====================
Netfilter fixes for net

The following patchset contains Netfilter fixes for your net tree,
they are:

1) Use mod_timer_pending() to avoid reactivating a dead expectation in
the h323 conntrack helper, from Liping Zhang.

2) Oneliner to fix a type in the register name defined in the nf_tables
header.

3) Don't try to look further when we find an inactive elements with no
descendants in the rbtree set implementation, otherwise we crash.

4) Handle valid zero CSeq in the SIP conntrack helper, from
Christophe Leroy.

5) Don't display a trailing slash in conntrack helper with no classes
via /proc/net/nf_conntrack_expect, from Liping Zhang.

6) Fix an expectation leak during creation from the nfqueue path, again
from Liping Zhang.

7) Validate netlink port ID in verdict message from nfqueue, otherwise
an injection can be possible. Again from Zhang.

8) Reject conntrack tuples with different transport protocol on
original and reply tuples, also from Zhang.

9) Validate offset and length in nft_exthdr, make sure they are under
sizeof(u8), from Laura Garcia Liebana.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+27 -21
+1 -1
include/uapi/linux/netfilter/nf_tables.h
··· 24 24 __NFT_REG_MAX, 25 25 26 26 NFT_REG32_00 = 8, 27 - MFT_REG32_01, 27 + NFT_REG32_01, 28 28 NFT_REG32_02, 29 29 NFT_REG32_03, 30 30 NFT_REG32_04,
+1 -1
net/netfilter/nf_conntrack_expect.c
··· 574 574 helper = rcu_dereference(nfct_help(expect->master)->helper); 575 575 if (helper) { 576 576 seq_printf(s, "%s%s", expect->flags ? " " : "", helper->name); 577 - if (helper->expect_policy[expect->class].name) 577 + if (helper->expect_policy[expect->class].name[0]) 578 578 seq_printf(s, "/%s", 579 579 helper->expect_policy[expect->class].name); 580 580 }
+2 -1
net/netfilter/nf_conntrack_h323_main.c
··· 1473 1473 "timeout to %u seconds for", 1474 1474 info->timeout); 1475 1475 nf_ct_dump_tuple(&exp->tuple); 1476 - mod_timer(&exp->timeout, jiffies + info->timeout * HZ); 1476 + mod_timer_pending(&exp->timeout, 1477 + jiffies + info->timeout * HZ); 1477 1478 } 1478 1479 spin_unlock_bh(&nf_conntrack_expect_lock); 1479 1480 }
+4 -6
net/netfilter/nf_conntrack_netlink.c
··· 1894 1894 1895 1895 if (!cda[CTA_TUPLE_ORIG] || !cda[CTA_TUPLE_REPLY]) 1896 1896 return -EINVAL; 1897 + if (otuple.dst.protonum != rtuple.dst.protonum) 1898 + return -EINVAL; 1897 1899 1898 1900 ct = ctnetlink_create_conntrack(net, &zone, cda, &otuple, 1899 1901 &rtuple, u3); ··· 2364 2362 return PTR_ERR(exp); 2365 2363 2366 2364 err = nf_ct_expect_related_report(exp, portid, report); 2367 - if (err < 0) { 2368 - nf_ct_expect_put(exp); 2369 - return err; 2370 - } 2371 - 2372 - return 0; 2365 + nf_ct_expect_put(exp); 2366 + return err; 2373 2367 } 2374 2368 2375 2369 static void ctnetlink_glue_seqadj(struct sk_buff *skb, struct nf_conn *ct,
+2 -2
net/netfilter/nf_conntrack_sip.c
··· 1383 1383 return NF_DROP; 1384 1384 } 1385 1385 cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1386 - if (!cseq) { 1386 + if (!cseq && *(*dptr + matchoff) != '0') { 1387 1387 nf_ct_helper_log(skb, ct, "cannot get cseq"); 1388 1388 return NF_DROP; 1389 1389 } ··· 1446 1446 return NF_DROP; 1447 1447 } 1448 1448 cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1449 - if (!cseq) { 1449 + if (!cseq && *(*dptr + matchoff) != '0') { 1450 1450 nf_ct_helper_log(skb, ct, "cannot get cseq"); 1451 1451 return NF_DROP; 1452 1452 }
+9 -2
net/netfilter/nft_exthdr.c
··· 59 59 const struct nlattr * const tb[]) 60 60 { 61 61 struct nft_exthdr *priv = nft_expr_priv(expr); 62 + u32 offset, len; 62 63 63 64 if (tb[NFTA_EXTHDR_DREG] == NULL || 64 65 tb[NFTA_EXTHDR_TYPE] == NULL || ··· 67 66 tb[NFTA_EXTHDR_LEN] == NULL) 68 67 return -EINVAL; 69 68 69 + offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET])); 70 + len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN])); 71 + 72 + if (offset > U8_MAX || len > U8_MAX) 73 + return -ERANGE; 74 + 70 75 priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); 71 - priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET])); 72 - priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN])); 76 + priv->offset = offset; 77 + priv->len = len; 73 78 priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]); 74 79 75 80 return nft_validate_register_store(ctx, priv->dreg, NULL,
+6 -4
net/netfilter/nft_rbtree.c
··· 70 70 } else if (d > 0) 71 71 parent = parent->rb_right; 72 72 else { 73 - found: 74 73 if (!nft_set_elem_active(&rbe->ext, genmask)) { 75 74 parent = parent->rb_left; 76 75 continue; ··· 83 84 } 84 85 } 85 86 86 - if (set->flags & NFT_SET_INTERVAL && interval != NULL) { 87 - rbe = interval; 88 - goto found; 87 + if (set->flags & NFT_SET_INTERVAL && interval != NULL && 88 + nft_set_elem_active(&interval->ext, genmask) && 89 + !nft_rbtree_interval_end(interval)) { 90 + spin_unlock_bh(&nft_rbtree_lock); 91 + *ext = &interval->ext; 92 + return true; 89 93 } 90 94 out: 91 95 spin_unlock_bh(&nft_rbtree_lock);