Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 299385 - sys-apps/hal-0.5.14: realpath(), fortify and -O2 cause SIGABRT
Summary: sys-apps/hal-0.5.14: realpath(), fortify and -O2 cause SIGABRT
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: High normal (vote)
Assignee: Daniel Gryniewicz (RETIRED)
URL: http://gcc.gnu.org/bugzilla/show_bug....
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-01-02 19:50 UTC by Peter Volkov (RETIRED)
Modified: 2010-01-11 15:20 UTC (History)
2 users (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Volkov (RETIRED) gentoo-dev 2010-01-02 19:50:54 UTC
realpath() built with >=gcc-4.3 (where FORTIFY is enabled by default) and -Ox where x>0 cause application to abort. Test case: the following code built with gcc -O2:

==========================================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>

#define PATH_MAX 1024

int
main (int argc, char *argv[])
{
    int ret;
    char device_file_or_mount_point[PATH_MAX];

    if (argc < 2 || strlen (argv[1]) == 0) {
        fprintf (stderr, "%s: pass relative path.\n", argv[0]);
        return 1;
    }

    realpath(argv[1], device_file_or_mount_point);

    return 0;
}
==========================================================================

produces:

./a.out /boot/
*** buffer overflow detected ***: ./a.out terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x37)[0x7f1adb1c33a7]
/lib/libc.so.6[0x7f1adb1c03d0]
/lib/libc.so.6[0x7f1adb1c0a9b]
./a.out(main+0x55)[0x7f1adb6518c5]
/lib/libc.so.6(__libc_start_main+0xe6)[0x7f1adb1015c6]
./a.out[0x7f1adb651789]
======= Memory map: ========
7f1adaecc000-7f1adaee2000 r-xp 00000000 09:02 1124776                    /lib64/libgcc_s.so.1
7f1adaee2000-7f1adb0e1000 ---p 00016000 09:02 1124776                    /lib64/libgcc_s.so.1
7f1adb0e1000-7f1adb0e2000 r--p 00015000 09:02 1124776                    /lib64/libgcc_s.so.1
7f1adb0e2000-7f1adb0e3000 rw-p 00016000 09:02 1124776                    /lib64/libgcc_s.so.1
7f1adb0e3000-7f1adb229000 r-xp 00000000 09:02 1221130                    /lib64/libc-2.9.so
7f1adb229000-7f1adb429000 ---p 00146000 09:02 1221130                    /lib64/libc-2.9.so
7f1adb429000-7f1adb42d000 r--p 00146000 09:02 1221130                    /lib64/libc-2.9.so
7f1adb42d000-7f1adb42e000 rw-p 0014a000 09:02 1221130                    /lib64/libc-2.9.so
7f1adb42e000-7f1adb433000 rw-p 7f1adb42e000 00:00 0 
7f1adb433000-7f1adb450000 r-xp 00000000 09:02 1220810                    /lib64/ld-2.9.so
7f1adb643000-7f1adb645000 rw-p 7f1adb643000 00:00 0 
7f1adb64d000-7f1adb64f000 rw-p 7f1adb64d000 00:00 0 
7f1adb64f000-7f1adb650000 r--p 0001c000 09:02 1220810                    /lib64/ld-2.9.so
7f1adb650000-7f1adb651000 rw-p 0001d000 09:02 1220810                    /lib64/ld-2.9.so
7f1adb651000-7f1adb652000 r-xp 00000000 09:02 467215                     /root/a.out
7f1adb851000-7f1adb852000 r--p 00000000 09:02 467215                     /root/a.out
7f1adb852000-7f1adb853000 rw-p 00001000 09:02 467215                     /root/a.out
7f1adc6d4000-7f1adc6f5000 rw-p 7f1adc6d4000 00:00 0                      [heap]
7fff2a27c000-7fff2a291000 rw-p 7ffffffea000 00:00 0                      [stack]
7fff2a3ff000-7fff2a400000 r-xp 7fff2a3ff000 00:00 0                      [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]


I found this bug with umount.hal helper which started to fail here after this commit:
http://cgit.freedesktop.org/hal/commit/?id=6d8eed9015a6ca648fe1dad575621b6ea959a748

But probably other applications are affected too. At least I found similar issue with python reported here:
https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/286334

Also I found that scilab has 6a5321bddceaf0e4761f29a507bfad6e1f3a7b33 commit (googable) that basically modifies realpath(r,a) call to a=realpath(r,NULL).
Comment 1 Peter Volkov (RETIRED) gentoo-dev 2010-01-04 14:21:41 UTC
Aha, as gcc devs pointed this is not a bug but feature of glibc. realpath manpage does not mentions this, but reading info libc it's explicitly stated:

On systems which define `PATH_MAX' ... the buffer must be large enough for a pathname of this size. 

Since HAL_PATH_MAX=1024 is smaller then PATH_MAX=4096 this causes this abort. hal should be fixed here.
Comment 2 Peter Volkov (RETIRED) gentoo-dev 2010-01-04 14:38:30 UTC
https://bugs.freedesktop.org/show_bug.cgi?id=25888
Comment 3 Peter Volkov (RETIRED) gentoo-dev 2010-01-04 19:47:20 UTC
Finally this is fixed upstream:
http://cgit.freedesktop.org/hal/commit/?id=a2c3dd5a04d79265772c09c4280606d5c2ed72c6

Please, grab the patch. And yes, it works here.

Comment 4 Daniel Gryniewicz (RETIRED) gentoo-dev 2010-01-07 13:31:21 UTC
Fixed in 0.5.14-r1.
Comment 5 Hugo Mildenberger 2010-01-09 12:20:00 UTC
(In reply to comment #4)
> Fixed in 0.5.14-r1.

This appears to be a semi-valid fix, valid only until a new kernel revision changes PATH_MAX within /usr/include/linux/limits.h

Also the dependency on -O appears to be strange behaviour. It stems from __USE_FORTIFY_LEVEL being defined differently on different optimization levels. 

With -O0 and sys-libs/glibc-2.11-r1, "__USE_FORTIFY_LEVEL > 0" evaluates to false in /usr/include/stdlib.h, 

948 #if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
949 # include <bits/stdlib.h>
950 #endif

while true with -O1, and this will then result in realpath_chk to be linked in.

Here is a test program:

#include <stdlib.h>
#include <stdio.h>

#if __USE_FORTIFY_LEVEL > 0
#warning "__USE_FORTIFIY_LEVEL > 0"
#endif

int main(int argc, char **argv) {
        char buffer[512];
        printf("__bos(buffer)=%d\n",__bos(buffer));
        const char *rp=realpath(argv[0],buffer);
        return rp!=NULL;
}


$ gcc -O0 test.c -o test0
$ gcc -O1 test.c -o test1
test.c:5:2: warning: #warning "__USE_FORTIFIY_LEVEL > 0"

$ ./test0
__bos(buffer)=512

$ ./test1
__bos(buffer)=512
*** buffer overflow detected ***: test1 - terminated
test1: buffer overflow attack in function <unknown> - terminated
Report to http://bugs.gentoo.org/
Aborted (core dumped)

So, is it correct for -Ox to change __USE_FORTIFY_LEVEL?


Comment 6 Peter Volkov (RETIRED) gentoo-dev 2010-01-09 19:32:05 UTC
(In reply to comment #5)
> This appears to be a semi-valid fix, valid only until a new kernel revision
> changes PATH_MAX within /usr/include/linux/limits.h

I had very same idea, but if you want this to change, report at upstream bug, please.
 
> So, is it correct for -Ox to change __USE_FORTIFY_LEVEL?

Check info gcc:

     NOTE: In Gentoo, `-D_FORTIFY_SOURCE=2' is set by default, and is
     activated when `-O' is set to 2 or higher.  This enables additional
     compile-time and run-time checks for several libc functions.  To
     disable, specify either `-U_FORTIFY_SOURCE' or
     `-D_FORTIFY_SOURCE=0'.

So I guess this is Gentoo specific, is documented and easy to override.
Comment 7 Daniel Gryniewicz (RETIRED) gentoo-dev 2010-01-11 15:20:34 UTC
This was the fix as applied upstream, so I'm going to leave it this way.  I already have to carry enough divergent patches as it is.