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: glibc env. vars. (again)
From: Matthew Kirkwood (weejockferret.lmh.ox.ac.uk)
Date: Wed May 24 2000 - 16:10:55 CDT


On Wed, 24 May 2000, Chris Evans wrote:

> AFAICT, glibc will happily accept the env. var. MALLOC_CHECK_ for suid
> programs (it doesn't use secure_getenv). Can anyone think of any
> problems with this.

None that aren't already problems. Except that things get printed
to stderr.

On RH6.1, this:

$ MALLOC_CHECK_=1 sudo strace -o ./str.ping sh -c 'exec ping -c1 0 2<&- 1<&-'

earns this:

write(2, "malloc: using debugging hooks\n", 30) = -1 EBADF (Bad file descriptor)
brk(0) = 0x805d294
brk(0x805d434) = 0x805d434

after the binary is mapped in, but before the first brk(n) call
(n!=0).

On 6.2, things are a little worse - malloc is not initialised until
the raw socket has been created[0], so we are rewarded with this:

$ MALLOC_CHECK_=1 sudo strace -o str.ping sh -c 'exec ping -c1 -n 0 2<&-'
(nb. only one fd closed this time)

socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 2
setuid(0) = 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
connect(4, {sin_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("0.0.0.0")}}, 16) = 0
getsockname(4, {sin_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("127.0.0.1")}}, [16]) = 0
close(4) = 0
bind(2, {sin_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}}, 16) = 0
setsockopt(2, IPPROTO_RAW1, [-6202], 4) = 0
write(2, "malloc: using debugging hooks\n", 30) = -1 EINVAL (Invalid argument)
brk(0) = 0x805d3d4
brk(0x805d4ac) = 0x805d4ac

So basically, it is possible to get any program which uses malloc,
as most do, to write to fd 2 early on. Triggering it later will be
harder, as you have to force the app to to a double free, or similar.

> In fact glibc probably needs a re-audit of which env. vars. it trusts.

Probably. It would be nice if there was a comprehensive list of
them somewhere.

Conclusions, as I see them:
 * we need a sysctl to turn suid / /dev/null hooking on and off
 * glibc probably shouldn't allow this

Matthew.

[0] I suspect this is because of a different ping, rather than
    any significant change between glibc 2.1.2 and 2.1.3.