Libnids IP Fragmentation Remote NULL Pointer Dereference
The designer of the popular library Rafal Wojtczuk (also known as nergal) discovered this vulnerability as we can read in the release notes of the 1.2.4 version of the library available here. As the release notes state, the vulnerability is located at src/ip_fragment.c and here is the equivalent code from 1.23 version of the library…
/* Memory limiting on fragments. Evictor trashes the oldest fragment queue until we are back under the low threshold. */ static void ip_evictor(void) { // fprintf(stderr, "ip_evict:numpack=%i\n", numpack); while (this_host->ip_frag_mem > IPFRAG_LOW_THRESH) { if (!this_host->ipqueue) panic("ip_evictor: memcount"); ip_free(this_host->ipqueue); } }
You can read from the comment the aim of this routine. The ‘while’ loop will iterate as long as integer ‘ip_frag_mem’ is larger than ‘IPFRAG_LOW_THRESH’ which is defined in the same source code file like this:
/* Fragment cache limits. We will commit 256K at one time. Should we cross that limit we will prune down to 192K. This should cope with even the most extreme cases without allowing an attacker to measurably harm machine performance. */ #define IPFRAG_HIGH_THRESH (256*1024) #define IPFRAG_LOW_THRESH (192*1024)
Next, if the ‘this_host->ipqueue’ that describes an entry in the “incomplete datagrams” queue is NULL, it will immediately call panic(). Otherwise, it will invoke ip_free() on this queue entry. However, ‘this_host’ pointer which keeps the fragments for this host might be NULL and thus, each access to the ‘ip_frag_mem’ integer will lead to a NULL pointer dereference which could later result in exploitable situations at ip_free() function. This was patched like this:
// fprintf(stderr, "ip_evict:numpack=%i\n", numpack); - while (this_host->ip_frag_mem > IPFRAG_LOW_THRESH) { + while (this_host && this_host->ip_frag_mem > IPFRAG_LOW_THRESH) { if (!this_host->ipqueue)
wb.
bind
April 4, 2010 at 19:43
yeah, excellent post xorl
kevin
April 4, 2010 at 22:16