[PLUTO-security] [Fwd: Netfilter Security Advisory: NAT Remote DOS (SACK mangle)]

Tom aka 'Dido' tom at pluto.linux.it
Mon Aug 4 12:01:33 CEST 2003


-----Forwarded Message-----

> From: Netfilter Core Team <coreteam a netfilter.org>
> To: Netfilter Announcement List <netfilter-announce a lists.netfilter.org>, Netfilter Mailinglist <netfilter a lists.netfilter.org>, Netfilter Development Mailinglist <netfilter-devel a lists.netfilter.org>
> Subject: [SECURITY] Netfilter Security Advisory: NAT Remote DOS (SACK mangle)
> Date: 02 Aug 2003 16:34:17 +0200
> 
>                   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 a netfilter.org
> 
> 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 a netfilter.org>             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



More information about the pluto-security mailing list