Found a dead-freeze bug, in xt_ipv4options.c -- patch provided

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



All,

I found this bug running Ubuntu 11.10, I managed to hang the operating system with the CPU pegged at 100% after sending it a malformed IP option packet. I had installed  the xtables-addons-dmks package installed via apt-get. The Ubuntu 11.10 distribution runs with the "3.0.0-12 #20-Ubuntu SMP" kernel. AFAIK, there should be little modifications to the code compared what is installed in git repository available on the web. 


To reproduce this issue:

1. Install Ubuntu 11.10
2. apt-get install xtables-addon-dmks
3. iptables -I INPUT 1 -m ipv4options --any -j LOG --log-prefix "PACKET WITH IP-OPTIONS DETECTED"

On a different computer (attacker),
4. Download, and install the isic (ip stack integrity checker) from http://isic.sourceforge.net
5. Run a test of the ip-stack to the victim (Ubuntu 11.10) computer (attacker: 192.168.111.100, victim: 192.168.111.200).

    sudo tcpsic -s 192.168.111.100,69 -d 192.168.111.200 -x 2 -m 1000 -T 30 -t 50
6. Victim PC freezes, no mouse, no movement; just dead. 


Further investigation showed that the xt_ipv4options.ko module was the culprit. The problem appeared to be that the ipv4option_rd() function entered a infinite loop when an ip-option of length 0 was encountered. I grepped the Linux kernel for similar code and modified the code in xt_ipv4options.c to correct this behavior. In addition, it seems like the --any option wasn't working correctly to begin with.

Any chances for this patch being accepted?

Regards,

- Eivind


--- /tmp/tmp.13465.100    2011-11-03 09:20:11.000000000 -0700
+++ xtables-addons/extensions/xt_ipv4options.c    2011-11-02 13:03:14.000000000 -0700
@@ -15,14 +15,32 @@
 #include "xt_ipv4options.h"
 #include "compat_xtables.h"
 
-static uint32_t ipv4options_rd(const uint8_t *data, int len)
+static uint32_t ipv4options_rd(const uint8_t *ptr, int len)
 {
     uint32_t opts = 0;
+    uint32_t olen = 0;
 
     while (len >= 2) {
-        opts |= 1 << (data[0] & 0x1F);
-        len  -= data[1];
-        data += data[1];
+    
+        /* Handle special options */
+        switch (*ptr) {
+        case IPOPT_END:
+            return opts;
+        case IPOPT_NOOP:
+            len--;
+            ptr++;
+            continue;
+        }
+        
+        /* Get the length of the option */
+        olen = ptr[1];
+        if (olen < 2 || olen > len)
+            return opts;
+        
+        /* Set the option bit, and incr/decr the invariants */
+        opts |= 1 << (*ptr & 0x1F);
+        len  -= olen;
+        ptr  += olen;
     }
 
     return opts;
@@ -36,13 +54,20 @@
     uint32_t opts = 0;
     uint16_t len  = ip_hdrlen(skb) - sizeof(struct iphdr);
 
-    if (len > 0)
+    if (len > 0) {
         opts = ipv4options_rd((const void *)iph +
                sizeof(struct iphdr), len);
+        if(info->flags & XT_V4OPTS_ANY) {
+            return  !!opts; /* !! to make bool value */
+        }else {
 
     opts ^= info->invert;
     opts &= info->map;
-    return (info->flags & XT_V4OPTS_ANY) ? opts : opts == info->map;
+            return (opts == info->map);
+        }        
+    }
+    
+    return 0;
 }

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux