| From 9f71c2033da8961d3f3f858daba0aa8188eb26f4 Mon Sep 17 00:00:00 2001 |
| From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> |
| Date: Tue, 3 Apr 2012 22:02:01 +0200 |
| Subject: [PATCH] netfilter: nf_ct_ipv4: packets with wrong ihl are invalid |
| |
| commit 07153c6ec074257ade76a461429b567cff2b3a1e upstream. |
| |
| It was reported that the Linux kernel sometimes logs: |
| |
| klogd: [2629147.402413] kernel BUG at net / netfilter / |
| nf_conntrack_proto_tcp.c: 447! |
| klogd: [1072212.887368] kernel BUG at net / netfilter / |
| nf_conntrack_proto_tcp.c: 392 |
| |
| ipv4_get_l4proto() in nf_conntrack_l3proto_ipv4.c and tcp_error() in |
| nf_conntrack_proto_tcp.c should catch malformed packets, so the errors |
| at the indicated lines - TCP options parsing - should not happen. |
| However, tcp_error() relies on the "dataoff" offset to the TCP header, |
| calculated by ipv4_get_l4proto(). But ipv4_get_l4proto() does not check |
| bogus ihl values in IPv4 packets, which then can slip through tcp_error() |
| and get caught at the TCP options parsing routines. |
| |
| The patch fixes ipv4_get_l4proto() by invalidating packets with bogus |
| ihl value. |
| |
| The patch closes netfilter bugzilla id 771. |
| |
| Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> |
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |
| index 2bb1f87051c4..a0af7a2d6117 100644 |
| --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |
| +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |
| @@ -84,6 +84,14 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, |
| *dataoff = nhoff + (iph->ihl << 2); |
| *protonum = iph->protocol; |
| |
| + /* Check bogus IP headers */ |
| + if (*dataoff > skb->len) { |
| + pr_debug("nf_conntrack_ipv4: bogus IPv4 packet: " |
| + "nhoff %u, ihl %u, skblen %u\n", |
| + nhoff, iph->ihl << 2, skb->len); |
| + return -NF_ACCEPT; |
| + } |
| + |
| return NF_ACCEPT; |
| } |
| |
| -- |
| 1.8.5.2 |
| |