OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
Subject: Re: local root on linux 2.2.15
From: Joseph Gooch (mrwizardPSU.EDU)
Date: Thu Jun 15 2000 - 15:41:27 CDT


> -----Original Message-----
> From: Bugtraq List [mailto:BUGTRAQSECURITYFOCUS.COM]On
> Behalf Of Peter
> da Silva
> Sent: Thursday, June 15, 2000 11:44 AM
> To: BUGTRAQSECURITYFOCUS.COM
> Subject: Re: local root on linux 2.2.15
>
>
> In article <87bt184i7z.fsfarabella.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