Date: Sat, 25 Jan 2020 10:54:24 -0500 From: Rich Felker <dalias@...c.org> To: Sergei Trofimovich <slyfox@...too.org> Cc: musl@...ts.openwall.com, libc-alpha@...rceware.org, gcc@....gnu.org, toolchain@...too.org Subject: Re: musl, glibc and ideal place for __stack_chk_fail_local On Sat, Jan 25, 2020 at 10:53:31AM +0000, Sergei Trofimovich wrote: > [ sending it to musl, glibc and gcc devel mailing list as we need > to build a consensus across the projects ] > > To support smash stack protection gcc emits __stack_chk_fail > calls on all targets. On top of that gcc emits __stack_chk_fail_local > calls at least on i386 and powerpc: > https://bugs.gentoo.org/706210#c9 > > gcc can either use libssp/libssp_nonshared fallback or rely on libc > to provide __stack_chk_fail. Where ideally should gcc pick > __stack_chk_fail_local? *Ideally*, GCC would emit it as a linkonce function section in every file that used it, the same way it does for __x86.get_pc_thunk.bx, etc. But that's not going to happen in old GCC versions so it's not a real solution even if new GCC were improved to do that. Second-best would be for __stack_chk_fail_local to be in the static-only part of libgcc. It's the same kind of compiler glue. This is plausible to patch into any GCC version when building. In reality, the path of least resistance is just continuing to have it in libssp_nonshared.a; this is what all the distros do. All it requires is patching the GCC specs so that -lssp_nonshared is always passed. > Looks like gcc/glibc and musl disagree on that: > - gcc: gcc either provides it from libssp_nonshared.a if libc has > no ssp support or pulls it from libc > - glibc: provides both __stack_chk_fail (deault) and > __stack_chk_fail_local (avoid PLT) symbols. > __stack_chk_fail_local comes from libc_nonshared.a and is > added to linker script as: $ cat /usr/lib/libc.so > OUTPUT_FORMAT(elf32-i386) > GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) ) There's no good reason for it to come from a "nonshared" lib file provided by libc rather than by the compiler. It's compiler ABI glue between the public API/ABI (__stack_chk_fail) and the PIC callers that don't want to be burdened by the GOT pointer setup to be able to call thru PLT. > - musl: provides only __stack_chk_fail (default) and > refuses to provide __stack_chk_fail_local: > https://www.openwall.com/lists/musl/2018/09/11/2 It's not that we refuse; it's that we can't, at least not without gratuitously changing other things. libc.so can't be made a linker script because then the real .so would have a different name and the DT_NEEDED would thereby change. (No, libc.so can't use DT_SONAME to control the name because then if you install /lib/ld-musl-$(ARCH).so.1 on a glibc-based system and run ldconfig, ldconfig will forcibly ln -s ld-musl-$(ARCH).so.1 /lib/libc.so, which is A Bad Thing.) There is a half-serious proposal to put it in crti.o which is always linked too, but that seems like an ugly hack to me... > This makes musl effectively not support ssp on i386 and probably powerpc. It's working for all dists because we/they just make GCC pass -lssp_nonshared via specs. > Currently gcc's assumption is that musl supports ssp symbols > from libc on all targets: > https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/configure.ac;h=a7521ee99436a7c12159bdde0471dc66d3c4288e;hb=HEAD#l6079 > > 6088 case "$target" in > 6089 *-*-musl*) > 6090 # All versions of musl provide stack protector > 6091 gcc_cv_libc_provides_ssp=yes;; > > Clearly that assumption is not correct as __stack_chk_fail_local > is not provided by musl and linking fails. > > This sounds like a expectation mismatch between gcc and musl > of what it takes to implement an ssp interface. > > What should we do to make it fixed long term and short term? > > Long term: > > Is there a vision of perfect end state agreed with gcc/glibc/musl > folk so we could just implement it? If there is none let's try to > form one. > > My understanding of requirements for libc that exposes ssp support: > - __stack_chk_fail is implemented as a default symbol > - __stack_chk_fail_local is implemented as a local symbol to avoid PLT. > (Why is it important? To avoid use of potentially already broken stack?) Because performance cost of -fstack-protector would go from 1-2% up to 5-10% on i386 and other archs where PLT contract requires a GOT register, since loading the GOT register is expensive (__x86.get_pc_thunk.* thunk itself is somewhat costly, and you throw away one of only a small number of available registers, increasing register pressure and hurting codegen). > My understanding of possible perfect end state: > 1. All libcs are required to somehow provide both __stack_chk_fail > and __stack_chk_fail_local: be it linker script, crt*.o files or an extra > libc_nonshared.a which gcc explicitly uses. Which one is best? > 2. All libcs are required to provide only __stack_chk_fail and gcc always > provides __stack_chk_local from libgcc.a, or from new libgcc_ssp.a. > Evntually glibc drops it's __stack_chk_fail definition. > 3. Your variant. > > How do you gcc/glibc/musl folk see it? Once we decide I'll file bugs > against agreed projects. At least gcc could explicitly document the > interface. > > Short term: > > While the above is not addressed what should we do about musl in gcc? > > Should gcc stop trying use musl on i386/powerpc here: > 6088 case "$target" in > 6089 *-*-musl*) > 6090 # All versions of musl provide stack protector > 6091 gcc_cv_libc_provides_ssp=yes;; > and fall back to libssp instead? Absolutely not. libssp is unsafe and creates new vulns/attack surface by doing introspective stuff after the process is already *known to be* in a compromised state. It should never be used. musl's __stack_chk_fail is safe and terminates immediately. The short term solution is just to continue what we're doing, adding -lssp_nonshared to specs. Ideally, though, GCC would just emit the termination inline (or at least have an option to do so) rather than calling __stack_chk_fail or the local version. This would additionally harden against the case where the GOT is compromised. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.