*** ip_firewall.c.old Tue Oct 17 21:06:18 1995 --- ip_firewall.c Wed Nov 29 22:51:04 1995 *************** *** 428,434 **** if ( ipfw_check_misc_flags(IP_FIREWALL_HEADFRAG,ip,NULL) ) { printf("HEAD-FRAGMENT "); } else if ( ipfw_check_misc_flags(IP_FIREWALL_TAILFRAG,ip,NULL) ) { ! printf("TAIL-FRAGMENT "); print_port = 0; } } --- 428,434 ---- if ( ipfw_check_misc_flags(IP_FIREWALL_HEADFRAG,ip,NULL) ) { printf("HEAD-FRAGMENT "); } else if ( ipfw_check_misc_flags(IP_FIREWALL_TAILFRAG,ip,NULL) ) { ! printf("TAIL-FRAGMENT (offset %d*8)", (ipfk_get_ip_off(ip) & IP_OFFMASK)); print_port = 0; } } *************** *** 722,727 **** --- 722,751 ---- } #endif + + /* + * If a TCP packet has a fragment offset of 1 then somebody may be trying + * to launch an overlapping fragment attack. + * Reject the packet (as per RFC 1858). + * + * Note that we reject the packet without even checking the filters to + * see if the TCP flags matter. We really don't have any choice. If + * an early filter just accepts all tail fragments (probably quite common) + * then this packet might get through even though later filters check the + * TCP_CONNECT flag. + * + * If every implementation of IP fragment reassembly was as carefully + * done as the BSD 4.4 implementation then this check wouldn't be necessary. + * + * See RFC 1858 for details. + */ + + if ( ipfk_get_ip_p(ip) == IPPROTO_TCP + && (ipfk_get_ip_off(ip) & IP_OFFMASK) == 1 ) { + xip_virtual_filter = 1; + return(0); + } + filter_index = 0; for ( fptr = chain; fptr != NULL; fptr = fptr->next ) {