On hardened systems, static linking of apps that use longjmp(3) (e.g. e2fsck, mv, bash, etc.) against glibc-2.11 fails with the following error: /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.2/../../../../lib64/libc.a(____longjmp_chk.o): In function `____longjmp_chk': (.text+0x75): undefined reference to `__GI___fortify_fail' The error is from an amd64/gcc-4.4.2-r1 (hardened-dev overlay) system, but I've replicated it with x86 systems as well as with gcc-4.3.4-r2. The in-tree glibc-2.10.1 package does not exhibit this behavior. I don't know which is at fault - sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S for calling __GI___fortify_fail or include/libc-symbols.h for not defining a valid libc_hidden_proto or hidden_proto in the presence of __ASSEMBLER__, or something else entirely, but this is as far as I can comfortably dig.
Same error if you build it with -hardenednopie or -vanilla gcc profile? And can you past emerge --info.
Created attachment 210583 [details] emerge --info from one of several test systems Same error on compiling the apps regardless of -vanilla GCC in use or not; haven't tried compiling glibc with the vanilla compiler (time), but given that the relevant code is thus: #ifdef PIC # define CALL_FAIL leaq longjmp_msg(%rip), %rdi; \ call __GI___fortify_fail #else # define CALL_FAIL movq $longjmp_msg, %rdi; \ call __fortify_fail #endif I have no doubt doing so would work, as there are other portions that call __fortify_fail and this is the only part of glibc that calls the __GI_ variant.
The same bug here: Portage 2.1.7.5 (hardened/linux/x86/10.0/desktop, gcc-4.3.4, glibc-2.11-r0, 2.6.31-11-generic i686) ================================================================= System uname: Linux-2.6.31-11-generic-i686-Genuine_Intel-R-_CPU_T2050_@_1.60GHz-with-gentoo-2.0.1 Timestamp of tree: Thu, 19 Nov 2009 07:45:01 +0000 app-shells/bash: 4.0_p35 dev-lang/python: 2.6.4, 3.1.1-r1 sys-apps/baselayout: 2.0.1 sys-apps/openrc: 0.5.2-r2 sys-apps/sandbox: 2.1 sys-devel/autoconf: 2.13, 2.63-r1 sys-devel/automake: 1.9.6-r2, 1.10.2, 1.11 sys-devel/binutils: 2.20 sys-devel/gcc-config: 1.4.1 sys-devel/libtool: 2.2.6b virtual/os-headers: 2.6.30-r1 ACCEPT_KEYWORDS="x86 ~x86" ACCEPT_LICENSE="* -@EULA" CBUILD="i686-pc-linux-gnu" CFLAGS="-O2 -march=native -pipe -fomit-frame-pointer" CHOST="i686-pc-linux-gnu" CONFIG_PROTECT="/etc" CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/fonts/fonts.conf /etc/gconf /etc/gentoo-release /etc/revdep-rebuild /etc/sandbox.d /etc/splash /etc/terminfo /etc/udev/rules.d" CXXFLAGS="-O2 -march=native -pipe -fomit-frame-pointer" DISTDIR="/var/cache/portage/distfiles" EMERGE_DEFAULT_OPTS="--with-bdeps y --nospinner --quiet-build" FEATURES="assume-digests buildpkg distlocks fixpackages news parallel-fetch protect-owned sandbox sfperms strict test test-fail-continue unmerge-logs unmerge-orphans userfetch" GENTOO_MIRRORS="http://mirrors.163.com/gentoo http://gentoo.aditsu.net" LANG="zh_CN.UTF-8" LC_ALL="C" LDFLAGS="-Wl,-O1 -Wl,--as-needed" LINGUAS="*" MAKEOPTS="-j3" PKGDIR="/var/cache/portage/packages" PORTAGE_COMPRESS="xz" PORTAGE_CONFIGROOT="/" PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages" PORTAGE_TMPDIR="/var/tmp" PORTDIR="/var/cache/portage/ebuilds/gentoo" PORTDIR_OVERLAY="/var/cache/portage/ebuilds/sunrise /var/cache/portage/ebuilds/gentoo-china /var/cache/portage/ebuilds/local" SYNC="rsync://mirror.averse.net/gentoo-portage" USE="X a52 aac acl acpi bash-completion berkdb bluetooth branding bzip2 cairo cdr cli consolekit cracklib crypt cups dbus dri dts dvd dvdr eds emboss encode evo fam flac gdbm gif gnome gpm gstreamer gtk hal hardened iconv ipv6 jpeg ldap libnotify lzma mad mikmod mmx mmxext modules mp3 mp4 mpeg mudflap ncurses nls nptl nptlonly ogg opengl openmp oss pam pcre pdf perl pic png ppds pppd python quicktime readline reflection sdl session spell spl sse sse2 ssl startup-notification svg sysfs tcpd thunar tiff truetype unicode urandom usb vim-syntax vorbis win32codecs x264 x86 xml xorg xulrunner xv xvid zlib" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci emu10k1 emu10k1x ens1370 ens1371 es1938 es1968 fm801 hda-intel intel8x0 intel8x0m maestro3 trident usb-audio via82xx via82xx-modem ymfpci" ALSA_PCM_PLUGINS="adpcm alaw asym copy dmix dshare dsnoop empty extplug file hooks iec958 ioplug ladspa lfloat linear meter mmap_emul mulaw multi null plug rate route share shm softvol" APACHE2_MODULES="actions alias auth_basic authn_alias authn_anon authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache dav dav_fs dav_lock deflate dir disk_cache env expires ext_filter file_cache filter headers include info log_config logio mem_cache mime mime_magic negotiation rewrite setenvif speling status unique_id userdir usertrack vhost_alias" ELIBC="glibc" INPUT_DEVICES="evdev" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LINGUAS="*" USERLAND="GNU" VIDEO_CARDS="intel"
I compared four systems and I believe this is an overlay specific issue with glibc-2.11. It does not happen on non-hardened gentoo and it does not happen on stock hardened gentoo. I tested with bash-4.0_p28 using --enable-static-link on the following systems: 1. amd64 hardened with the overlay toolchain: gcc-4.4.2-r1, binutils-2.20, gcc-2.11 2. x86 hardened with the overlay toolchain: gcc-4.4.2-r1, binutils-2.20, gcc-2.11 2. amd64 stock hardened: gcc-4.3.4, binutils-2.20, gcc-2.11 3. amd64 no-hardening: gcc-4.3.4, binutils-2.20, glibc-2.11 Only #1 and #2 gave the undefined reference to `__GI___fortify_fail' in ____longjmp_chk. All of them, however, had two other link issues: 1) Using the get/setpwnam family of functions in statically linked applications requires at runtime the shared libraries from the glibc version used for linking, and 2) There were multiple definition of free/malloc/realloc. The first of these is typical of statically linking against glibc but I'm not sure what's causing the second problem.
My question would be whether the overlay GCC defines PIC whereas the stock hardened one does not. This particular piece of code is from vanilla upstream glibc-2.11 (checked the git repo) and is triggered by having PIC defined when glibc is compiled. In other words, I have little doubt whether the hardened compiler is triggering this issue, but it seems to be in the glibc code and not what the hardened team has done.
1. unpack new stage3 2. emerge --sync 3. emerge -avDNu world 4. emerge binutils 2.20 and glibc 2.11 5. USE="static" ebuild busybox compile AND busybox fail with (.text+0x75): undefined reference to `__GI___fortify_fail' Arch amd64 CFLAGS = -march=core2 -O2 -pipe USE="" stage3 date 20091119
I also hit the error on stock hardened gentoo proceeding as in Comment #6. This is not an overlay specific issue. The problem in my comment #4 is that I was using a glibc which had been compiled -hardenednopie. To properly reproduce the error, you need pie enabled when compiling glibc before compiling/statically linking bash, busybox, etc. I think that may be the problem with Comment #2. Just switch the compiler profile after having compiled glibc pie/nopie isn't not sufficient.
files/eblits/common.eblit add -DPIC to CPPFLAGS if we have hardened and pie enable by default. The CPPFLAGS is pass to all objects. GCC pass -DPIC to cc1 when we build ____longjmp_chk.o /usr/libexec/gcc/x86_64-pc-linux-gnu/4.4.2/cc1 -E -lang-asm -quiet -nostdinc -v -I../include -I/var/tmp/portage/sys-libs/glibc-2.11/work/build-x86-x86_64-pc-linux-gnu-nptl/debug -I/var/tmp/portage/sys-libs/glibc-2.11/work/build-x86-x86_64-pc-linux-gnu-nptl -I../sysdeps/i386/elf -I../nptl/sysdeps/unix/sysv/linux/i386/i686 -I../sysdeps/unix/sysv/linux/i386/i686 -I../nptl/sysdeps/unix/sysv/linux/i386 -I../sysdeps/unix/sysv/linux/i386 -I../nptl/sysdeps/unix/sysv/linux -I../nptl/sysdeps/pthread -I../sysdeps/pthread -I../sysdeps/unix/sysv/linux -I../sysdeps/gnu -I../sysdeps/unix/common -I../sysdeps/unix/mman -I../sysdeps/unix/inet -I../sysdeps/unix/sysv/i386 -I../nptl/sysdeps/unix/sysv -I../sysdeps/unix/sysv -I../sysdeps/unix/i386 -I../nptl/sysdeps/unix -I../sysdeps/unix -I../sysdeps/posix -I../sysdeps/i386/i686/fpu -I../nptl/sysdeps/i386/i686 -I../sysdeps/i386/i686 -I../sysdeps/i386/i486 -I../nptl/sysdeps/i386/i486 -I../sysdeps/i386/fpu -I../nptl/sysdeps/i386 -I../sysdeps/i386 -I../sysdeps/wordsize-32 -I../sysdeps/ieee754/ldbl-96 -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/ieee754 -I../sysdeps/generic/elf -I../sysdeps/generic -I../nptl -I.. -I../libio -I. -imultilib 32 -MD /var/tmp/portage/sys-libs/glibc-2.11/work/build-x86-x86_64-pc-linux-gnu-nptl/debug/____longjmp_chk.d -MF /var/tmp/portage/sys-libs/glibc-2.11/work/build-x86-x86_64-pc-linux-gnu-nptl/debug/____longjmp_chk.o.dt -MP -MT /var/tmp/portage/sys-libs/glibc-2.11/work/build-x86-x86_64-pc-linux-gnu-nptl/debug/____longjmp_chk.o -D_LIBC_REENTRANT -U_FORTIFY_SOURCE -DPIC -U_FORTIFY_SOURCE -DPIC -U_FORTIFY_SOURCE -DPIC -DASSEMBLER -DGAS_SYNTAX -isystem /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.2/include -isystem /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.2/include-fixed -isystem /usr/include -include ../include/libc-symbols.h ../sysdeps/unix/sysv/linux/i386/____longjmp_chk.S -fno-strict-overflow -m32 -march=i686 -fno-stack-protector -fPIE -fno-directives-only -o /var/tmp/portage/sys-libs/glibc-2.11/temp/ccztCSrY.s cat /sysdeps/unix/sysv/linux/i386/____longjmp_chk.S the ifdef PIC part ifdef PIC # define CALL_FAIL movl %ebx, %ecx; \ cfi_register(%ebx,%ecx); \ LOAD_PIC_REG (bx); \ leal longjmp_msg@GOTOFF(%ebx), %eax; \ call __GI___fortify_fail@PLT #else # define CALL_FAIL movl $longjmp_msg, %eax; \ call __fortify_fail #endif So it use __GI___fortyfy_fail
Adding CPPFLAGS-____longjmp_chk.o = -UPIC to debug/Makefile make it use __fortify_fail instead. And busybox coampile fine with static. But the CPPFLAGS from the environment pass -DPIC after the CPPFLAGS-____longjmp_chk.o = -UPIC so it fail to applay -UPIC to the ____longjmp_chk.o We need a fix for that. Haven't tested that busybox works.
Created attachment 211348 [details, diff] patch for common.eblit So we don't use append-cppflags when >= glibc-2.11
Created attachment 211349 [details, diff] Updated hardened-pie patch to fix bug #293637 Updated the hardened-pie patch to fix this bug.
@Toolchain any hints or clue to fix it? Will the patches be okey?
i dont think that's the way to go. why not fix the longjmp_chk code to check SHARED instead of PIC.
Created attachment 211351 [details, diff] glibc-hidden-jumptarget-fortify-fail.patch well, some places use PIC and mean PIC while others use PIC and mean SHARED. probably better to use HIDDEN_JUMPTARGET().
(In reply to comment #14) > Created an attachment (id=211351) [details] > glibc-hidden-jumptarget-fortify-fail.patch > > well, some places use PIC and mean PIC while others use PIC and mean SHARED. > probably better to use HIDDEN_JUMPTARGET(). > ____longjmp_chk.o.dt -MT /var/tmp/portage/sys-libs/glibc-2.11/work/build-x86-x86_64-pc-linux-gnu-nptl/debug/____longjmp_chk.o ../sysdeps/unix/sysv/linux/i386/____longjmp_chk.S: Assembler messages: ../sysdeps/unix/sysv/linux/i386/____longjmp_chk.S:76: Error: junk `@PLT' after expression make[2]: *** [/var/tmp/portage/sys-libs/glibc-2.11/work/build-x86-x86_64-pc-linux-gnu-nptl/debug/____longjmp_chk.o] Error 1
so put the @PLT inside of the ()
(In reply to comment #16) > so put the @PLT inside of the () > Still fail the same way HIDDEN_JUMPTARGET (__fortify_fail@PLT)
I tested the patch in Comment #14 on both 32 and 64 bits archs. Both lead to the error in Comment #15. Removing the @PLT allows glibc to compile. Both busybox and bash then compile and statically link fine.
oh, i missed sysdeps/i386/sysdep.h which redefines some macros to automatically append the @PLT. so you dont need to specify it yourself -- both CALL_FAILs should end with: call HIDDEN_JUMPTARGET(__fortify_fail)
Created attachment 211527 [details, diff] Updated patch with @PLT and the ia64 part removed. Removed the @PLT and the ia64 part. Can't test the ia64 part so i removed that part.
i didnt really expect you to test the ia64 code. i can do that myself. you didnt say though whether the parts you can test worked for you. all three work for me, so i queued the patch http://sources.gentoo.org/gentoo/src/patchsets/glibc/2.11/1020_all_glibc-longjmp-chk-hidden-fortify.patch?rev=1.1
(In reply to comment #21) > i didnt really expect you to test the ia64 code. i can do that myself. you > didnt say though whether the parts you can test worked for you. > > all three work for me, so i queued the patch > http://sources.gentoo.org/gentoo/src/patchsets/glibc/2.11/1020_all_glibc-longjmp-chk-hidden-fortify.patch?rev=1.1 > Me and Anythony have test it on x86 and amd64 and it works fine on hardened.
why is this not yet added to the tree or hardened-dev ? thanks
ok - sorry ! just saw that it's included in the PATCH_VER="5" patchset I remember it still failing to compile and showing that error, ... I'll re-emerge it later and post more information (first have to look whether it's the exact same error message)