[15374] in bugtraq

home help back first fref pref prev next nref lref last post

Re: local root on linux 2.2.15

daemon@ATHENA.MIT.EDU (Joseph Gooch)
Fri Jun 16 14:32:58 2000

MIME-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Message-ID:  <009f01bfd70a$14955900$0600000a@WIZPII400>
Date:         Thu, 15 Jun 2000 16:41:27 -0400
Reply-To: Joseph Gooch <mrwizard@PSU.EDU>
From: Joseph Gooch <mrwizard@PSU.EDU>
X-To:         Peter da Silva <peter@SCARYDEVIL.ORG>
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <200006151544.KAA0000009515@grendel.eng.baileynm.com>

> -----Original Message-----
> From: Bugtraq List [mailto:BUGTRAQ@SECURITYFOCUS.COM]On
> Behalf Of Peter
> da Silva
> Sent: Thursday, June 15, 2000 11:44 AM
> To: BUGTRAQ@SECURITYFOCUS.COM
> Subject: Re: local root on linux 2.2.15
>
>
> In article <87bt184i7z.fsf@arabella.intern.opera.no> you write:
> > Always check the return value of system calls.  Always.  Always.
> > Always.
> [...]
> >   cap_user_header_t header;
> >   cap_user_data_t data;
> >   header = malloc(8);
> >   data = malloc(12);
> >   header->pid = 0;
> >   header->version = _LINUX_CAPABILITY_VERSION;
> >   data->inheritable = data->effective = data->permitted = 0;
>
> Two bugs here:
>
> 	1. If sizeof(cap_user_header_t) or sizeof(cap_user_data_t)
> 	   increases, you'll get a buffer overflow in the malloc()ed
> 	   data. This isn't as bad as a buffer overflow on stack,
> 	   because it's almost impossible to exploit for anything but
> 	   a DOS attack, but it's easy to avoid:
>
> 	   header = malloc(sizeof (cap_user_header_t) );
> 	   data = malloc(sizeof (cap_user_data_t) );
>
> 	2. Ironically, you're not checking the return value of a system
> 	   call, namely brk() or sbrk() (or maybe mmap(), depending on
> 	   how they're implementing malloc() in Lunix these
> days). Before
> 	   using header or data, check that malloc() succeeded.
>
> 	   if(! (header = malloc(sizeof (cap_user_header_t) ) ) ) {
> 		perror("malloc: header");
> 		return or exit();
> 	   }
> 	   if(! (data = malloc(sizeof (cap_user_data_t) ) ) ) {
> 		perror("malloc: data");
> 		return or exit();
> 	   }
>
> >   capset(header, data);
>
> I don't have a recent Linux box to check, but isn't this a
> system call?
> If this fails, what happens? In the sample code, nothing
> bad...  but if
> you don't get in the habit of automatically writing robust code you're
> going to be reading one of these alerts some day with your
> name on it...
> as the victim.

The proper way to do this would be to use libcap :)  I.e. the following
pseudocode:

cap_t cap_d;

cap_d = cap_init();
if (!cap_d) {perror("Malloc failed"); exit(-1); }
cap_clear(cap_d);
if (cap_set_proc(cap_d)) {perror("capset failed"); exit(-1); }
cap_free(&cap_d);


Of course either code is acceptible, the libcap code is just more robust.
The proper checks could be added to his model just as easily.

Joe Gooch

home help back first fref pref prev next nref lref last post