Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sat, 25 Jan 2020 10:53:31 +0000
From: Sergei Trofimovich <slyfox@...too.org>
To: musl@...ts.openwall.com, libc-alpha@...rceware.org, gcc@....gnu.org,
 toolchain@...too.org
Subject: musl, glibc and ideal place for __stack_chk_fail_local

[ 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?

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 ) )
- 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

This makes musl effectively not support ssp on i386 and probably powerpc.

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?)

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?

If it makes sense I'll create a bug against gcc.

Thanks!

-- 

  Sergei

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.