Remote DoS vulnerability in Linux kernel 2.6.x

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Kevin
Date:  
To: plug-discuss
Subject: Remote DoS vulnerability in Linux kernel 2.6.x
http://www.securityfocus.com/archive/1/367615

------------
To: BugTraq
Subject: Remote DoS vulnerability in Linux kernel 2.6.x
Date: Jun 30 2004 10:57AM
Author: Adam Osuchowski <adwol polsl gliwice pl>
Message-ID: <>

1. Overview
-----------

There is a remotely exploitable bug in all Linux kernel 2.6 series due
to using incorrect variable type. Vulnerability is connected to
netfilter subsystem and may cause DoS. It's disclosed only when using
iptables with rules matching TCP options (i.e. --tcp-option). There is
no difference what action is taking up by matching rule.

Vulnerability was detected on i386 architecture. The other ones weren't
tested but it seems to be vulnerable too.

2. Details
----------

Problem lies in tcp_find_option() function
(net/ipv4/netfilter/ip_tables.c).

There is local array `opt' defined as:

    char opt[60 - sizeof(struct tcphdr)];


which contains TCP options extracted from packet. Function mentioned
above searches for specified option in this array.

Options in TCP packet, with some exceptions, are organized in the
following way:

    Octet no.    Length    Field
    -----------------------------
        0    1    Opcode
        1    1    Length of all option (N + 2)
        2    N    Params



The function iterates over options in array:

    for (i = 0; i < optlen; ) {
        if (opt[i] == option) return !invert;
        if (opt[i] < 2) i++;
        else i += opt[i+1]?:1;
    }


moving counter by the option length.

But, in case the `length' value is greater than 127, the value of this
octet in `opt' is implicitly casted to char, which results in negative
number and the loop counter moving back. In some cases it is possible,
that counter cycles throught the contents of this array infinitely.

3. Impact
---------

After sending one suitably prepared TCP packet to victim host, kernel
goes into infinite loop consuming all CPU resources, rendering the box
unresponsable. Of course, there is no need to have a shell access to
attacked host.

4. Exploitation
---------------

Example of packet-of-death:

0x0000: 4500 0030 1234 4000 ff06 e83f c0a8 0001
0x0010: c0a8 0002 0400 1000 0000 0064 0000 0064
0x0020: 7000 0fa0 dc6a 0000 0204 05b4 0101 04fd

5. Fix
------

There is only need to change type of `opt' array from signed char to
unsigned (or, better to u_int8_t) as it was defined in 2.4 kernel or
prior to version 1.16 of net/ipv4/netfilter/ip_tables.c file.

--- net/ipv4/netfilter/ip_tables.c.orig    2004-04-04 05:36:47.000000000
+0200
+++ net/ipv4/netfilter/ip_tables.c    2004-06-24 21:24:26.000000000 +0200
@@ -1461,7 +1461,7 @@
         int *hotdrop)
 {
     /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
-    char opt[60 - sizeof(struct tcphdr)];
+    u_int8_t opt[60 - sizeof(struct tcphdr)];
     unsigned int i;


     duprintf("tcp_match: finding option\n");


6. Credits
----------

Vulnerability was discovered, identified and fixed by Adam Osuchowski
and Tomasz Dubinski.

--
## Adam Osuchowski adwol polsl gliwice pl, adwol silesia linux org pl
## Silesian University of Technology, Computer Centre Gliwice, Poland


---------------------------------------------------
PLUG-discuss mailing list -
To subscribe, unsubscribe, or to change you mail settings:
http://lists.PLUG.phoenix.az.us/mailman/listinfo/plug-discuss