Synopsis: IP options denial of service
NetBSD versions: NetBSD 1.4.2 
Thanks to: Jason Thorpe, Bill Sommerfeld
Reported in NetBSD Security Advisory: SA2000-002


*** sys/netinet/ip.h.orig	1998/02/10 01:26:44	1.18
--- sys/netinet/ip.h	2000/05/05 03:06:42	1.18.8.1
***************
*** 68,74 ****
  	u_int8_t  ip_p;			/* protocol */
  	u_int16_t ip_sum;		/* checksum */
  	struct	  in_addr ip_src, ip_dst; /* source and dest address */
! };
  
  #define	IP_MAXPACKET	65535		/* maximum packet size */
  
--- 68,74 ----
  	u_int8_t  ip_p;			/* protocol */
  	u_int16_t ip_sum;		/* checksum */
  	struct	  in_addr ip_src, ip_dst; /* source and dest address */
! } __attribute__((__packed__));
  
  #define	IP_MAXPACKET	65535		/* maximum packet size */
  
***************
*** 142,149 ****
  		 struct	ipt_ta {
  			struct in_addr ipt_addr;
  			n_time ipt_time;
! 		 } ipt_ta[1];
! 	} ipt_timestamp;
  };
  
  /* flag bits for ipt_flg */
--- 142,149 ----
  		 struct	ipt_ta {
  			struct in_addr ipt_addr;
  			n_time ipt_time;
! 		 } ipt_ta[1] __attribute__((__packed__));
! 	} ipt_timestamp __attribute__((__packed__));
  };
  
  /* flag bits for ipt_flg */

*** sys/netinet/ip_input.c.orig	2000/03/02 10:24:18	1.82.2.5
--- sys/netinet/ip_input.c	2000/05/06 16:43:25	1.82.2.6
***************
*** 919,925 ****
  				break;
  			}
  			off--;			/* 0 origin */
! 			if (off > optlen - sizeof(struct in_addr)) {
  				/*
  				 * End of source route.  Should be for us.
  				 */
--- 919,925 ----
  				break;
  			}
  			off--;			/* 0 origin */
! 			if ((off + sizeof(struct in_addr)) > optlen) {
  				/*
  				 * End of source route.  Should be for us.
  				 */
***************
*** 961,967 ****
  			 * If no space remains, ignore.
  			 */
  			off--;			/* 0 origin */
! 			if (off > optlen - sizeof(struct in_addr))
  				break;
  			bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
  			    sizeof(ipaddr.sin_addr));
--- 961,967 ----
  			 * If no space remains, ignore.
  			 */
  			off--;			/* 0 origin */
! 			if ((off + sizeof(struct in_addr)) > optlen)
  				break;
  			bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
  			    sizeof(ipaddr.sin_addr));