Netfilter Core Team Security Advisory CVE: CAN-2003-0467 Subject: Netfilter / NAT Remote DoS Released: 01 Aug 2003 Effects: Under limited circumstances, a remote user may be able to crash a machine doing Network Address Translation (NAT). Estimated Severity: Medium. Systems Affected: Linux 2.4.20 kernels and recent 2.5 kernels with CONFIG_IP_NF_NAT_FTP or CONFIG_IP_NF_NAT_IRC enabled, or the ip_nat_ftp or ip_nat_irc modules loaded, on which ftp and irc users are not packet filtered out. Solution: BEST: Upgrade to Linux kernels 2.4.21 (stable), or apply the patch below. OR: As a workaround, the modules can be removed, or iptables can be used to block untrusted users from initiating ftp or irc connections through the NAT machine. Details: This was verified by Rusty Russell on 2.4.20, and verified fixed with this patch. Vendor Statement: Red Hat: All of the 2.4.20-based kernels shipped by Red Hat already contain the patch and are not vulnerable to this issue. Others: unknown Credits: The problem was found, and the fix implemented by the Netfilter Core Team. Contact: coreteam@xxxxxxxxxxxxx diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal linux-2.4.21-pre7/net/ipv4/netfilter/ip_nat_helper.c working-2.4.21-pre7-sackadjust/net/ipv4/netfilter/ip_nat_helper.c --- linux-2.4.21-pre7/net/ipv4/netfilter/ip_nat_helper.c 2003-04-06 15:26:48.000000000 +1000 +++ working-2.4.21-pre7-sackadjust/net/ipv4/netfilter/ip_nat_helper.c 2003-04-14 23:18:38.000000000 +1000 @@ -366,54 +365,49 @@ sack_adjust(struct tcphdr *tcph, } -/* TCP SACK sequence number adjustment, return 0 if sack found and adjusted */ -static inline int +/* TCP SACK sequence number adjustment. */ +static inline void ip_nat_sack_adjust(struct sk_buff *skb, - struct ip_conntrack *ct, - enum ip_conntrack_info ctinfo) + struct ip_conntrack *ct, + enum ip_conntrack_info ctinfo) { - struct iphdr *iph; struct tcphdr *tcph; - unsigned char *ptr; - int length, dir, sack_adjusted = 0; + unsigned char *ptr, *optend; + unsigned int dir; - iph = skb->nh.iph; - tcph = (void *)iph + iph->ihl*4; - length = (tcph->doff*4)-sizeof(struct tcphdr); + tcph = (void *)skb->nh.iph + skb->nh.iph->ihl*4; + optend = (unsigned char *)tcph + tcph->doff*4; ptr = (unsigned char *)(tcph+1); dir = CTINFO2DIR(ctinfo); - while (length > 0) { - int opcode = *ptr++; + while (ptr < optend) { + int opcode = ptr[0]; int opsize; switch (opcode) { case TCPOPT_EOL: - return !sack_adjusted; + return; case TCPOPT_NOP: - length--; + ptr++; continue; default: - opsize = *ptr++; - if (opsize > length) /* no partial opts */ - return !sack_adjusted; + opsize = ptr[1]; + /* no partial opts */ + if (ptr + opsize > optend || opsize < 2) + return; if (opcode == TCPOPT_SACK) { /* found SACK */ if((opsize >= (TCPOLEN_SACK_BASE +TCPOLEN_SACK_PERBLOCK)) && !((opsize - TCPOLEN_SACK_BASE) % TCPOLEN_SACK_PERBLOCK)) - sack_adjust(tcph, ptr-2, + sack_adjust(tcph, ptr, &ct->nat.info.seq[!dir]); - - sack_adjusted = 1; } - ptr += opsize-2; - length -= opsize; + ptr += opsize; } } - return !sack_adjusted; } /* TCP sequence number adjustment */ -- - Harald Welte <laforge@xxxxxxxxxxxxx> http://www.netfilter.org/ ============================================================================ "Fragmentation is like classful addressing -- an interesting early architectural error that shows how much experimentation was going on while IP was being designed." -- Paul Vixie
Attachment:
pgp00518.pgp
Description: PGP signature