[redirected to freebsd-ipfw]

Certainly, there is a bug.
Please test with attached patch.

On Thu, Oct 26, 2000 at 04:01:07PM +0200, Harti Brandt wrote:
> 
> Hi,
> 
> I stumbled over an interesting problem: the current kernel's NFS client
> code blocks when reading files of size 2828 byte over NFSv3 (see
> kern/22309). Today I tracked the problem down. It appears, that an IP
> packet cannot be reassembled, when the last fragment of it is from 1 to 7
> bytes long.
> 
> For some reason I have IP_FIREWALL and IP_FIREWALL_DEFAULT_TO_ACCEPT in my
> kernel config (well, the reason is, that I wanted to play with
> 'sting'). Although there is a comment in ip_fw.c that it is not a problem,
> when an incoming packet is a fragment with off!=0, it appears to be a
> problem, if the packet is too short to contain a UDP header. ip_fw insists
> on having an UDP header (around line 1002) and drops the packet as a bogus
> fragment, if it is too short for a header. I think, this is wrong.
> 
> Because I'm not too firm with the firewall code, I have no fix.
> 

-- 
Ruslan Ermilov          Oracle Developer/DBA,
[EMAIL PROTECTED]           Sunbay Software AG,
[EMAIL PROTECTED]          FreeBSD committer,
+380.652.512.251        Simferopol, Ukraine

http://www.FreeBSD.org  The Power To Serve
http://www.oracle.com   Enabling The Information Age
Index: ip_fw.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.c,v
retrieving revision 1.146
diff -u -p -w -r1.146 ip_fw.c
--- ip_fw.c     2000/10/26 00:16:12     1.146
+++ ip_fw.c     2000/10/26 15:57:53
@@ -970,21 +970,20 @@ ip_fw_chk(struct ip **pip, int hlen,
                                    goto bogusfrag;                     \
                                ip = mtod(*m, struct ip *);             \
                                *pip = ip;                              \
-                               offset = (ip->ip_off & IP_OFFMASK);     \
                            }                                           \
                        } while (0)
 
        /*
         * Collect parameters into local variables for faster matching.
         */
+       proto = ip->ip_p;
+       src_ip = ip->ip_src;
+       dst_ip = ip->ip_dst;
        offset = (ip->ip_off & IP_OFFMASK);
-       {
+       if (offset == 0) {
            struct tcphdr *tcp;
            struct udphdr *udp;
 
-           dst_ip = ip->ip_dst ;
-           src_ip = ip->ip_src ;
-           proto = ip->ip_p ;
            /*
             * warning - if offset != 0, port values are bogus.
             * Not a problem for ipfw, but could be for dummynet.
@@ -1014,6 +1013,7 @@ ip_fw_chk(struct ip **pip, int hlen,
            default :
                break;
            }
+       }
 #undef PULLUP_TO
            last_pkt.src_ip = ntohl(src_ip.s_addr) ;
            last_pkt.dst_ip = ntohl(dst_ip.s_addr) ;
@@ -1021,7 +1021,6 @@ ip_fw_chk(struct ip **pip, int hlen,
            last_pkt.src_port = ntohs(src_port) ;
            last_pkt.dst_port = ntohs(dst_port) ;
            last_pkt.flags = flags ;
-       }
 
        if (*flow_id) {
                /* Accept if passed first test */

Reply via email to