[15374] in bugtraq
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