[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#647553: gcc-4.6: fails LTO with PIE: sparc_get_pc_thunk referenced in .text, defined in discarded section



Package: gcc-4.6
Version: 4.6.1-13
Severity: important

Currently, compiling mksh with hardening enabled breaks on sparc (debian)
and sparc64 (debian-ports) with identical problems. I tracked this down to
the use of PIE in the final link (not object file generation) in combina-
tion with LTO using the linker plugin.

It boils down to this:

gcc -g -O2 -fPIE -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -Wall -Wextra -fno-strict-aliasing -fstack-protector-all -fwrapv -flto=jobserver -std=gnu99 -fPIE -pie -Wl,-z,relro -Wl,-z,now -fuse-linker-plugin -o mksh  lalloc.o edit.o eval.o exec.o expr.o funcs.o histrap.o jobs.o lex.o main.o misc.o shf.o syn.o tree.o var.o strlcpy.o printf.o  || for _f in ${tcfn}*; do test x"${_f}" = x"mksh.1" || rm -f "${_f}"; done
edit.o (symbol from plugin): warning: memset used with constant zero length parameter; this could be due to transposed parameters
`__sparc_get_pc_thunk.l7' referenced in section `.text' of /tmp/ccx38SGj.ltrans21.ltrans.o: defined in discarded section `.text.__sparc_get_pc_thunk.l7.2528[__sparc_get_pc_thunk.l7.2528]' of /tmp/ccx38SGj.ltrans21.ltrans.o
`__sparc_get_pc_thunk.l7' referenced in section `.text' of /tmp/ccx38SGj.ltrans26.ltrans.o: defined in discarded section `.text.__sparc_get_pc_thunk.l7.2625[__sparc_get_pc_thunk.l7.2625]' of /tmp/ccx38SGj.ltrans26.ltrans.o
collect2: ld returned 1 exit status

Omitting either (a) -fPIE (twice) and -pie (once), or (b) -flto=jobserver
and -fuse-linker-plugin (both once), lets the link succeed with the binary
result being usable. (To fully test it, run './test.sh -v' afterwards.)

I’ve included detailed reproduction instructions using a Debian porterbox;
also note the warning about memset in edit.o that disappears when not using
LTO (I’ve been unable to find such use in the source code, so I assume it
must be compiler-emitted), but that’s not a cause of the breakage (as I’ve
seen it happen on platforms where mksh builds fine, too):


tg@sperger:~$ dget http://ftp.de.debian.org/debian/pool/main/m/mksh/mksh_40.2-3.dsc
dget: retrieving http://ftp.de.debian.org/debian/pool/main/m/mksh/mksh_40.2-3.dsc
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1926  100  1926    0     0  11862      0 --:--:-- --:--:-- --:--:-- 15165
dget: retrieving http://ftp.de.debian.org/debian/pool/main/m/mksh/mksh_40.2.orig.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  319k  100  319k    0     0  1156k      0 --:--:-- --:--:-- --:--:-- 1258k
dget: retrieving http://ftp.de.debian.org/debian/pool/main/m/mksh/mksh_40.2-3.diff.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 95334  100 95334    0     0   541k      0 --:--:-- --:--:-- --:--:--  629k
dscverify: can't find any Debian keyrings
tg@sperger:~$ dpkg-source -x mksh_40.2-3.dsc
gpgv: keyblock resource `/home/tg/.gnupg/trustedkeys.gpg': file open error
gpgv: Signature made Tue Oct 25 23:33:18 2011 UTC using RSA key ID E99007E0
gpgv: Can't check signature: public key not found
dpkg-source: warning: failed to verify signature on ./mksh_40.2-3.dsc
dpkg-source: info: extracting mksh in mksh-40.2
dpkg-source: info: unpacking mksh_40.2.orig.tar.gz
dpkg-source: info: applying mksh_40.2-3.diff.gz
dpkg-source: info: upstream files that have been modified:
 mksh-40.2/Build.sh
 mksh-40.2/check.t
 mksh-40.2/dot.mkshrc
 mksh-40.2/edit.c
 mksh-40.2/eval.c
 mksh-40.2/exec.c
 mksh-40.2/expr.c
 mksh-40.2/funcs.c
 mksh-40.2/histrap.c
 mksh-40.2/jobs.c
 mksh-40.2/lalloc.c
 mksh-40.2/lex.c
 mksh-40.2/main.c
 mksh-40.2/misc.c
 mksh-40.2/mksh.1
 mksh-40.2/sh.h
 mksh-40.2/shf.c
 mksh-40.2/syn.c
 mksh-40.2/tree.c
 mksh-40.2/var.c
tg@sperger:~$ dchroot sid
Executing shell in chroot: /org/chroot/sid
(sid)tg@sperger:~$ cd mksh-40.2
(sid)tg@sperger:~/mksh-40.2$ HAVE_CAN_WALL=0 USE_PRINTF_BUILTIN=1 CC='gcc' CFLAGS='-g -O2 -fPIE -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -Wall -Wextra' CPPFLAGS='-D_FORTIFY_SOURCE=2 -DMKSH_BINSHREDUCED' LDFLAGS='-fPIE -pie -Wl,-z,relro -Wl,-z,now' LIBS='' dash Build.sh -r -c lto

[…]

gcc -g -O2 -fPIE -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -Wall -Wextra -fno-strict-aliasing -fstack-protector-all -fwrapv -flto=jobserver -std=gnu99 -I. -D_FORTIFY_SOURCE=2 -DMKSH_BINSHREDUCED -D_GNU_SOURCE -DSETUID_CAN_FAIL_WITH_EAGAIN -DHAVE_ATTRIBUTE_BOUNDED=0 -DHAVE_ATTRIBUTE_FORMAT=1 -DHAVE_ATTRIBUTE_NONNULL=1 -DHAVE_ATTRIBUTE_NORETURN=1 -DHAVE_ATTRIBUTE_UNUSED=1 -DHAVE_ATTRIBUTE_USED=1 -DHAVE_SYS_BSDTYPES_H=0 -DHAVE_SYS_FILE_H=1 -DHAVE_SYS_MKDEV_H=0 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_BSTRING_H=0 -DHAVE_GRP_H=1 -DHAVE_LIBGEN_H=1 -DHAVE_LIBUTIL_H=0 -DHAVE_PATHS_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_ULIMIT_H=1 -DHAVE_VALUES_H=1 -D_FILE_OFFSET_BITS=64 -DHAVE_CAN_INTTYPES=1 -DHAVE_CAN_UCBINTS=1 -DHAVE_CAN_INT8TYPE=1 -DHAVE_CAN_UCBINT8=1 -DHAVE_RLIM_T=1 -DHAVE_SIG_T=1 -DHAVE_SYS_SIGNAME=0 -DHAVE_SYS_SIGLIST=1 -DHAVE_STRSIGNAL=0 -DHAVE_GETRUSAGE=1 -DHAVE_KILLPG=1 -DHAVE_MKNOD=0 -DHAVE_MKSTEMP=1 -DHAVE_NICE=1 -DHAVE_REVOKE=0 -DHAVE_SETLOCALE_CTYPE=1 -DHAVE_LANGINFO_CODESET=1 -DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 -DHAVE_STRCASESTR=1 -DHAVE_STRLCPY=0 -DHAVE_FLOCK_DECL=0 -DHAVE_REVOKE_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_PRINTF_BUILTIN -c printf.c
gcc -g -O2 -fPIE -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -Wall -Wextra -fno-strict-aliasing -fstack-protector-all -fwrapv -flto=jobserver -std=gnu99 -fPIE -pie -Wl,-z,relro -Wl,-z,now -fuse-linker-plugin -o mksh  lalloc.o edit.o eval.o exec.o expr.o funcs.o histrap.o jobs.o lex.o main.o misc.o shf.o syn.o tree.o var.o strlcpy.o printf.o  || for _f in ${tcfn}*; do test x"${_f}" = x"mksh.1" || rm -f "${_f}"; done
edit.o (symbol from plugin): warning: memset used with constant zero length parameter; this could be due to transposed parameters
`__sparc_get_pc_thunk.l7' referenced in section `.text' of /tmp/ccx38SGj.ltrans21.ltrans.o: defined in discarded section `.text.__sparc_get_pc_thunk.l7.2528[__sparc_get_pc_thunk.l7.2528]' of /tmp/ccx38SGj.ltrans21.ltrans.o
`__sparc_get_pc_thunk.l7' referenced in section `.text' of /tmp/ccx38SGj.ltrans26.ltrans.o: defined in discarded section `.text.__sparc_get_pc_thunk.l7.2625[__sparc_get_pc_thunk.l7.2625]' of /tmp/ccx38SGj.ltrans26.ltrans.o
collect2: ld returned 1 exit status
(sid)tg@sperger:~/mksh-40.2$ gcc -g -O2  -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -Wall -Wextra -fno-strict-aliasing -fstack-protector-all -fwrapv -flto=jobserver -std=gnu99  -Wl,-z,relro -Wl,-z,now -fuse-linker-plugin -o mksh  lalloc.o edit.o eval.o exec.o expr.o funcs.o histrap.o jobs.o lex.o main.o misc.o shf.o syn.o tree.o var.o strlcpy.o printf.o
edit.o (symbol from plugin): warning: memset used with constant zero length parameter; this could be due to transposed parameters
(sid)tg@sperger:~/mksh-40.2$ ./mksh -c 'ls; print $KSH_VERSION'
Build.sh    dot.mkshrc  eval.o  funcs.c    jobs.o    main.c  mksh.1      shf.c         syn.c    var.c
Rebuild.sh  edit.c      exec.c  funcs.o    lalloc.c  main.o  printf.c    shf.o         syn.o    var.o
check.pl    edit.o      exec.o  histrap.c  lalloc.o  misc.c  printf.o    signames.inc  test.sh  var_spec.h
check.t     emacsfn.h   expr.c  histrap.o  lex.c     misc.o  sh.h        strlcpy.c     tree.c
debian      eval.c      expr.o  jobs.c     lex.o     mksh    sh_flags.h  strlcpy.o     tree.o
@(#)MIRBSD KSH R40 2011/10/25
(sid)tg@sperger:~/mksh-40.2$ rm mksh
(sid)tg@sperger:~/mksh-40.2$ gcc -g -O2 -fPIE -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -Wall -Wextra -fno-strict-aliasing -fstack-protector-all -fwrapv  -std=gnu99 -fPIE -pie -Wl,-z,relro -Wl,-z,now -o mksh  lalloc.o edit.o eval.o exec.o expr.o funcs.o histrap.o jobs.o lex.o main.o misc.o shf.o syn.o tree.o var.o strlcpy.o printf.o
(sid)tg@sperger:~/mksh-40.2$ ./mksh -c 'ls; print $KSH_VERSION'
Build.sh    dot.mkshrc  eval.o  funcs.c    jobs.o    main.c  mksh.1      shf.c         syn.c    var.c
Rebuild.sh  edit.c      exec.c  funcs.o    lalloc.c  main.o  printf.c    shf.o         syn.o    var.o
check.pl    edit.o      exec.o  histrap.c  lalloc.o  misc.c  printf.o    signames.inc  test.sh  var_spec.h
check.t     emacsfn.h   expr.c  histrap.o  lex.c     misc.o  sh.h        strlcpy.c     tree.c
debian      eval.c      expr.o  jobs.c     lex.o     mksh    sh_flags.h  strlcpy.o     tree.o
@(#)MIRBSD KSH R40 2011/10/25
(sid)tg@sperger:~/mksh-40.2$ 



Reply to: