This patch fixes a possible DoS where invalid frames that use conntrack helpers can continuously log to the kernel log. This could be a particular problem for embedded systems with small or slow filesystems. Fix is to use the LOG_INVALID macro which only logs if the proper sysctl setting in enabled.
This patch is currently under review with the netfilter developers. Signed-off-by: Peter Holland <[email protected]> --- --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target/linux/generic-2.6/patches-2.6.32/982-log_invalid_in_ct_helper.patch Mon Dec 12 13:33:36 2011 -0800 @@ -0,0 +1,68 @@ +--- linux-2.6.32.27/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-12-05 16:02:12.978083979 -0800 ++++ linux-2.6.32.27-new/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2011-12-05 16:06:40.207447349 -0800 +@@ -97,6 +97,7 @@ + const struct nf_conn_help *help; + const struct nf_conntrack_helper *helper; + unsigned int ret; ++ struct net *net; + + /* This is where we call the helper: as the packet goes out. */ + ct = nf_ct_get(skb, &ctinfo); +@@ -112,11 +113,14 @@ + if (!helper) + goto out; + ++ net = nf_ct_net(ct); ++ + ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), + ct, ctinfo); + if (ret != NF_ACCEPT) { +- nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL, +- "nf_ct_%s: dropping packet", helper->name); ++ if (LOG_INVALID(net, nf_ct_protonum(ct))) ++ nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL, ++ "nf_ct_%s: dropping packet", helper->name); + return ret; + } + +@@ -125,7 +129,7 @@ + + seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); + if (!seq_adjust || !seq_adjust(skb, ct, ctinfo)) { +- NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop); ++ NF_CT_STAT_INC_ATOMIC(net, drop); + return NF_DROP; + } + } +--- linux-2.6.32.27/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c 2011-12-05 16:02:28.515586023 -0800 ++++ linux-2.6.32.27-new/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c 2011-12-05 16:10:08.718080829 -0800 +@@ -155,7 +155,7 @@ + unsigned int ret, protoff; + unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data; + unsigned char pnum = ipv6_hdr(skb)->nexthdr; +- ++ struct net *net; + + /* This is where we call the helper: as the packet goes out. */ + ct = nf_ct_get(skb, &ctinfo); +@@ -170,6 +170,8 @@ + if (!helper) + goto out; + ++ net = nf_ct_net(ct); ++ + protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, + skb->len - extoff); + if (protoff > skb->len || pnum == NEXTHDR_FRAGMENT) { +@@ -179,8 +181,9 @@ + + ret = helper->help(skb, protoff, ct, ctinfo); + if (ret != NF_ACCEPT) { +- nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL, +- "nf_ct_%s: dropping packet", helper->name); ++ if (LOG_INVALID(net, nf_ct_protonum(ct))) ++ nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL, ++ "nf_ct_%s: dropping packet", helper->name); + return ret; + } + out: _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
