Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 66553 - (toolchain) artsdsp stack smashing attack in function read()
Summary: (toolchain) artsdsp stack smashing attack in function read()
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Hardened (show other bugs)
Hardware: All Linux
: High normal (vote)
Assignee: The Gentoo Linux Hardened Team
URL:
Whiteboard: audit
Keywords:
Depends on: 65892
Blocks:
  Show dependency tree
 
Reported: 2004-10-06 10:58 UTC by Ole Tange
Modified: 2006-01-30 17:25 UTC (History)
2 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
Output from emerge info (emerge-info,2.50 KB, text/plain)
2004-10-06 10:59 UTC, Ole Tange
Details
strace (fil,22.60 KB, text/plain)
2004-10-10 23:30 UTC, Ole Tange
Details
Simple testcase (libtester.c,768 bytes, text/x-csrc)
2004-11-21 13:55 UTC, Malte S. Stretz
Details
Full strace (libtester.strace,5.60 KB, text/plain)
2004-11-21 13:56 UTC, Malte S. Stretz
Details
untested patch against ssp.c (glibc-2.3.3-ssp-canary-init-crash.patch,404 bytes, patch)
2005-01-19 17:07 UTC, Malte S. Stretz
Details | Diff
a working patch (ssp.c-no-overload-crash.patch,2.54 KB, patch)
2005-01-21 13:54 UTC, Malte S. Stretz
Details | Diff
patch against glibc-2.3.4.20040808-r1 (glibc-2.3.4.20040808-r1.ebuild.patch,499 bytes, patch)
2005-01-21 13:54 UTC, Malte S. Stretz
Details | Diff
a more complete testcase (tester.mk,1.37 KB, text/plain)
2005-01-21 14:00 UTC, Malte S. Stretz
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ole Tange 2004-10-06 10:58:33 UTC
After compiling KDE with a hardened gcc I artsdsp reports:

stack smashing attack in function read()
Aborted

Reproducible: Always
Steps to Reproduce:
1. USE=hardened emerge gcc
2. USE=hardened emerge arts
3. artsdsp ls
Comment 1 Ole Tange 2004-10-06 10:59:17 UTC
Created attachment 41237 [details]
Output from emerge info
Comment 2 solar (RETIRED) gentoo-dev 2004-10-10 20:49:07 UTC
I don't us qt/arts myself so I can't test this but a ssp in a read()
should never happen. Please post the uncompressed output of
strace -v -i -f artsdsp
Comment 3 Ole Tange 2004-10-10 23:30:28 UTC
Created attachment 41509 [details]
strace
Comment 4 Malte S. Stretz 2004-11-21 13:55:51 UTC
Created attachment 44433 [details]
Simple testcase

It took me a few days to track this bug down.  It seems like the tsack smash
protector always hits in if you LD_PRELOAD a lib which overrides read(2) and at
some point hands the access down to the original read routine.

I stripped down the file artsdsp.c to the attached file.  Compiled as an so and
try
  strace -vif -E LD_PRELOAD="libtester.so.0.0.0:/lib/libdl.so.2" test

Whichever app you call that way, the very first read() command will die out
like this (full strace follows):
[400642ca] rt_sigaction(SIGRTMIN, {0x4015b170, [], 0}, NULL, 8) = 0
[400642ca] rt_sigaction(SIGRT_1, {0x4015b1b0, [], 0}, NULL, 8) = 0
[400642ca] rt_sigaction(SIGRT_2, {0x4015b280, [], 0}, NULL, 8) = 0
[4006450d] rt_sigprocmask(SIG_BLOCK, [RTMIN], NULL, 8) = 0
[4006450d] rt_sigprocmask(SIG_UNBLOCK, [RT_1], NULL, 8) = 0
[400f25a6] _sysctl({{CTL_KERN, KERN_VERSION}, 2, 0xbfffeaa4, 32, (nil), 0}) = 0

[400e3258] open("/dev/urandom", O_RDONLY) = 3
[400e3498] write(2, "read(3, 0x4014ec84, 4): in\n", 27read(3, 0x4014ec84, 4):
in
) = 27
[400e3498] write(2, "init(): in\n", 11init(): in
) = 11
[400eaeab] brk(0)			= 0x804e000
[400eaeab] brk(0x806f000)		= 0x806f000
[400e3498] write(2, "init(): out\n", 12init(): out
) = 12
[400e3418] read(3, "\260\367{_", 4)	= 4
[400e3498] write(2, "read(): out\n", 12read(): out
) = 12
[4006450d] rt_sigprocmask(SIG_BLOCK, ~[ABRT], NULL, 8) = 0
[400e3498] write(2, "test: stack smashing attack in f"..., 44test: stack
smashing attack in function read) = 44
[400e3498] write(2, "()\n", 3()
)	   = 3
[400f3682] socket(PF_UNIX, SOCK_DGRAM, 0) = 4
[400f3596] sendto(4, "<2>test: stack smashing attack i"..., 47, 0,
{sa_family=AF_UNIX, path="/dev/log"}, 110) = 47
[400642ca] rt_sigaction(SIGABRT, {SIG_DFL}, NULL, 8) = 0
[400c22d7] getpid()			= 21296
[40064591] kill(21296, SIGABRT) 	= 0
[40064591] --- SIGABRT (Aborted) @ 0 (0) ---
upeek: ptrace(PTRACE_PEEKUSER,21296,48,0): No such process
[????????] +++ killed by SIGABRT +++

I guess that reading from /dev/urandom is line 84 in
sysdeps/unix/sysv/linux/ssp.c in glibc-2.3.4.20040808-r1?  So why does it die
there?
Comment 5 Malte S. Stretz 2004-11-21 13:56:44 UTC
Created attachment 44434 [details]
Full strace
Comment 6 Malte S. Stretz 2004-11-22 16:07:12 UTC
Maybe it helps if __libc_read() was used instead of read() in ssp.c?  Haven't tried that though.
Comment 7 Kevin F. Quinn (RETIRED) gentoo-dev 2005-01-19 16:39:11 UTC
Just had the same, with skype.

artsdsp is a shell script which sets LD_PRELOAD to /usr/kde/3.3/lib/libartsdsp.so.0:/usr/kde/3.3/lib/libartsc.so.0:/lib/libdl.so.2

Quick experiments narrow it down to libartsdsp.so.0:

$ LD_PRELOAD=/usr/kde/3.3/lib/libartsdsp.so.0 /bin/echo
echo: stack smashing attack in function read()
Aborted

$ readelf -s /usr/kde/3.3/lib/libartsdsp.so.0 | grep read
    20: 00000000   118 FUNC    GLOBAL DEFAULT  UND arts_read
    29: 000019b0   248 FUNC    GLOBAL DEFAULT   10 read

so the culprit is a read() function defined in libartsdsp.so.0 (not the libc read() function).

At this point we need someone conversant with KDE innards.  artsc/artscbackend.cc contains a read() function, which presumably has the stack overflow.  However it's not immediately obvious.
Comment 8 Malte S. Stretz 2005-01-19 17:07:25 UTC
Created attachment 49002 [details, diff]
untested patch against ssp.c

This is (AFAICS) not a KDE/aRts problem but a problem with the glibc smash
stack protector.  That one uses read() to get the canary from /dev/urandom. 
Unfortunately does artsdsp LD_PRELOAD its own read() routine which has his own
canary which doesn't get initialized correctly.  So this affects all apps which
overload read(), probably also esound -- have a look at the testcase I attached
to have a sample independent from arts.

My guess is that it would help if the SSP initialization routine used
__libc_read() (which is not overloadable), like the attached patch does.  I'd
try it if I knew how to install (and debug) a parrallel glibc install without
trashing my system :)
Comment 9 Ole Tange 2005-01-20 00:56:33 UTC
> I'd try it if I knew how to install (and debug) a 
> parrallel glibc install without trashing my system :)

Consider taking a look at vserver. Vserver can run 
mutiple linux-installations on the same hardware box.
(Kind of VMware but without the overhead).

When you trash one installation you simply do a cp -a.
Comment 10 Kevin F. Quinn (RETIRED) gentoo-dev 2005-01-20 12:49:20 UTC
Just tried the suggestion in #8, replacing read() with __libc_read() - it Works For Me, great stuff.

Perhaps all the libc calls made in ssp.c (there are quite a few) should be coded to the internal names to avoid them being overloaded in this way - does that make sense?


Comment 11 solar (RETIRED) gentoo-dev 2005-01-20 13:36:20 UTC
Kevin, yes it sure does make logical sense to convert all the functions over to libc internal ones. There was another bug open about that but the ball got dropped on it.
Comment 12 Malte S. Stretz 2005-01-21 13:54:16 UTC
Created attachment 49140 [details, diff]
a working patch

This is a tested patch against ssp.c.  I replaced all calls which have internal
protected equivalences with those.  It works but its possible that I made some
errors as I could not find any documentation at all on those glibc macros and
internals.

Please review.
Comment 13 Malte S. Stretz 2005-01-21 13:54:51 UTC
Created attachment 49141 [details, diff]
patch against glibc-2.3.4.20040808-r1
Comment 14 Malte S. Stretz 2005-01-21 14:00:09 UTC
Created attachment 49142 [details]
a more complete testcase

Try 'gmake -f tester.mk' -- if the bug is still there, the SSP will hit in
libtester_::read(), else in tester_::main():

(0) otherland /mnt/dummy/tmp/ssptest # gmake -f tester.mk test
make: Circular Makefile.c <- Makefile dependency dropped.
rm -f libtester_.so libtester_.c
rm -f tester_ tester_.c
sed -ne '/^libtester_.c.in/,/^[^\t]/{s/^\(\t\|[^\t].*\)//;p}' Makefile >
libtester_.c
cc -fstack-protector -rdynamic libtester_.c -o libtester_.so -shared
sed -ne '/^tester_.c.in/,/^[^\t]/{s/^\(\t\|[^\t].*\)//;p}' Makefile > tester_.c

cc -fstack-protector tester_.c -o tester_
LD_PRELOAD="./libtester_.so:/lib/libdl.so.2" ./tester_
libtester_.c:22
libtester_.c:14
libtester_.c:17
libtester_.c:25
tester_: stack smashing attack in function read()
make: *** [test] Aborted
(2) otherland /mnt/dummy/tmp/ssptest # chroot /mnt/dummy/
otherland / # cd tmp/ssptest/
otherland /tmp/ssptest # gmake -f tester.mk test
make: Circular Makefile.c <- Makefile dependency dropped.
LD_PRELOAD="./libtester_.so:/lib/libdl.so.2" ./tester_
tester_.c:6
tester_.c:8
tester_: stack smashing attack in function main()
make: *** [test] Aborted
Comment 15 Kevin F. Quinn (RETIRED) gentoo-dev 2005-01-27 09:17:21 UTC
Been running the most recent patch from #13 here for a couple of days without any trouble.  Test case from #14 gives the same results as described in #14.  artsdsp no longer fails.
Comment 16 Kevin F. Quinn (RETIRED) gentoo-dev 2005-01-27 09:22:03 UTC
Just seen bug #65892, which seems to be heading for a fix that'll achieve the same result.  I'd suggest the fix in that bug could make this bug obsolete.
Comment 17 Kevin F. Quinn (RETIRED) gentoo-dev 2006-01-30 17:25:56 UTC
This has been fixed for a while, now.