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
Created attachment 41237 [details] Output from emerge info
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
Created attachment 41509 [details] strace
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?
Created attachment 44434 [details] Full strace
Maybe it helps if __libc_read() was used instead of read() in ssp.c? Haven't tried that though.
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.
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 :)
> 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.
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?
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.
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.
Created attachment 49141 [details, diff] patch against glibc-2.3.4.20040808-r1
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
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.
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.
This has been fixed for a while, now.