The IGMP (or Internet group management protocol) is today's standard for delivering multicast functionality to Internet hosts. The Linux kernel incorporates a base set of the IGMPv2 and IGMPv3 specifications and is subdivided into two logical parts:
* The IGMP/IP networking module responsible for network level operation which is only compiled into the kernel if configured for multicasting
* The socket API delivering multicasting capabilities to user level applications which is always available on Linux
The ip_mc_source() function that can be called through the user API (more explicitly: 'IP_(UN)BLOCK_SOURCE', 'IP_ADD/DROP_SOURCE_MEMBERSHIP' as well as 'MCAST_(UN)BLOCK_SOURCE' and 'MCAST_JOIN/LEAVE_SOURCE_GROUP' socket 'SOL_IP' level options) suffers from a serious kernel hang and kernel memory overwrite problem.
IP_SF_SOCKLIST structure counter
It is possible to decrement the 'sl_count' counter of the 'ip_sf_socklist' structure to be 0xffffffff (that is -1 as signed integer, see attached PoC code) with the consequence that a repeated call to the above function will start a kernel loop counting from 0 to UINT_MAX. This will cause a kernel hang for minutes (depending on the machine speed).
Right after that the whole kernel memory following the kmalloc'ated buffer will be shifted by 4 bytes causing an immediate machine reboot under normal operating conditions. If properly exploited this will lead to elevated privileges.
It is quite obvious that moving around all kernel memory following a kmalloc'ated buffer is a bad idea. However if done very carefully this may give a local attacker elevated privileges. This flaw is easier to exploit on an SMP machine (where one thread can interrupt the copy loop before the kernel gets completely destroyed).
On uniprocessor configurations the exploit-ability is questionable since there is no other exit condition from the copy loop than a kernel oops if we hit a non existing page. If an attacker manages to trick the kernel to allocate the buffer just right before the end of kernel's physical memory mapping and also manages to place for example a LDT just after that buffer, exploitation will occur on a uniprocessor machine. Still, the easiest exploitation for this bug is to crash the running kernel.
Kernel memory reading
Due to the above mentioned bug under certain conditions it is possible to read a fairly significant amount of kernel memory through the ip_mc_msfget() and ip_mc_gsfget() (user API) functions.
igmp_marksources() function
The igmp_marksources() function from the network module is called in the context of an IGMP group query received from the network and suffers from an out of bound read access to kernel memory. It happens because the received IGMP message's parameters are not validated properly. This flaw is remotely exploitable on Linux machines with multicasting support if and only if an application has bound a multicast socket.
This problem is a remote kernel vulnerability. There are several conditions that must be meet for remote exploitation to occur:
* The kernel has been compiled with multicasting support and is configured to process incoming IGMP packets. Moreover, an attacker must be able to send group queries (IGMP_HOST_MEMBERSHIP_QUERY messages) to the vulnerable machine.
* An application running on the vulnerable machine with a bound multicast socket with attached source filter. There are numerous applications using multicasting like video conferencing or routing software, just to name few. The attacker must also know the IGMP group used to perform the attack.
By looking at these proc entries it is possible to determine if a system is vulnerable to this bug: /proc/net/igmp
/proc/net/mcfilter
If both exist and are non-empty, the running kernel is vulnerable.
Since the kernel does not validate the 'ih3->nsrcs' IGMP parameter, the igmp_marksources() internal kernel function may access kernel memory outside of the allocated socket buffer holding the IGMP message. Depending on the relative position of the socket buffer in the kernel memory this may lead to an immediate kernel crash.
Another consequence is that the kernel will spend most of the CPU time on scanning useless kernel data right after the buffer if the 'nsrcs' parameter is very high. If a continuous flow of prepared IGMP packets is sent to a vulnerable machine, it may stop to process other network traffic. For an average machine only a moderate IGMP packet flow is required. This may lead to serious problems in case of routing software.
Proof Of Concept
/*
* Linux igmp.c local DoS
* Warning: this code will crash your machine!
*
* gcc -O2 mreqfck.c -o mreqfck
*
* Copyright (c) 2004 iSEC Security Research. All Rights Reserved.
*
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
* AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
* WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
*
*/