This is sources Bugzilla
Bugzilla Version 2.17.5
Bugzilla Bug 7065
  Support building glibc with -fstack-protector or -fstack-protector-all Last modified: 2009-06-04 22:25
     Query page      Enter new bug
Bug#: 7065   Hardware:   Reporter: Nix <nix@esperi.org.uk>
Host: Target: Build:
Product:     Add CC:
Component:   Version:   CC:
Remove selected CCs
Status: REOPENED   Priority:  
Resolution:   Severity:  
Assigned To: Ulrich Drepper <drepper@redhat.com>   Target Milestone:  
Flags: Requestee:
  backport ()
  examined ()
  testsuite ()
Summary:
Keywords:

Attachment Description Type Created Actions
stack-chk-fail-nonrecursive.diff stack protector support for glibc patch 2008-12-04 00:55 Edit | Diff
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 7065 depends on: Show dependency tree
Show dependency graph
Bug 7065 blocks:

Additional Comments:


Leave as REOPENED 
Mark bug as waiting for feedback
Mark bug as suspended
Accept bug (change status to ASSIGNED)
Resolve bug, changing resolution to
Resolve bug, mark it as duplicate of bug #
Reassign bug to
Reassign bug to owner of selected component

View Bug Activity   |   Format For Printing


Description:   Last confirmed: 0000-00-00 00:00 Opened: 2008-12-04 00:38
Several distributions, including Gentoo, have patches which attempt to make 
glibc build when compiled with -fstack-protector. None of them that I have 
found actually work: at best, they make it crash instantly, because none of 
them suppress generation of stack guards around functions called before the 
guard is initialized (or even before ld-linux.so.2 has relocated itself).

For now I'd consider it more of a maintenance burden than it's worth to
isolate the parts of ld.so that are called before security_init(), so
I've just arranged to avoid using the stack-protector in ld.so, and
marked the few things not also in the dynamic loader which are used
during pre-guard-init static library initialization with
-fno-stack-protector. (An improvement might be to mark these with
-fno-stack-protector only when building the static library.)

I can't think of a way to isolate the functions in this set automatically, but 
if you get it wrong it's easy to tell because you get an instant coredump, so 
it's easy to prevent the set of -fno-stack-protectored functions from 
bitrotting, manually maintained though it must be.)

You can still use -fstack-protector-all in all the rest of glibc, which
is an order of magnitude more code than ld.so and includes really hairy
stuff like malloc() and lots of functions that themselves call
string-manipulation functions, so I'd say this is a pretty good
tradeoff.

Some of the module tests need adjustment: they don't link against
libc, so must specify -fno-stack-protector; the same is true of some of the 
configury, taking care not to specify that unless GCC is actually capable of 
accepting -fstack-protector. (We specify -lssp and leave the stack protector on 
where possible in configure tests.)

Results of tests and patch against glibc 2.9 following shortly.

------- Additional Comment #1 From Ulrich Drepper 2008-12-04 00:44 -------
Never going to happen.

------- Additional Comment #2 From Nix 2008-12-04 00:53 -------
test environment: 2.6.27.7 kernel+headers, glibc 2.8, GCC 4.3.3 20081121 
(prerelease), binutils 2.19.

config flags (my standard set for this machine):

/usr/packages/glibc/2.9/configure --prefix=/usr --enable-shared \
    --enable-profile --disable-bounded --enable-bind-now        \
    --enable-add-ons=nptl,libidn --enable-kernel=2.6.25         \
    --enable-check-abi=warn --enable-omitfp                     \
    --enable-stackguard-randomization TIMEOUTFACTOR=5

Below, PASS means 'baseline test failures only'. (I also compared
configure output to verify that -fstack-protector addition did not
change the results of any configure tests, and verified that the
appropriate -fstack-protector actually appeared in gcc commandlines at
the appropriate times.)

baseline:                              PASS, by definition
patch applied, no flags specified:     PASS
-fstack-protector in CFLAGS:           PASS
-fstack-protector-all in CFLAGS:       one failure due to #7066, buffer overrun
--without-stack-protector:             PASS
--with-stack-protector:                PASS
--with-stack-protector=all:            one failure due to #7066, buffer overrun

Test failures for baseline (unpatched):

math/test-ildoubl.out:

testing long double (inline functions)
Failure: Test: expm1 (1) == M_El - 1.0
Result:
 is:          1.71828182845904523532e+00   0xd.bf0a8b14576953500000p-3
 should be:   1.71828182845904523543e+00   0xd.bf0a8b14576953600000p-3
 difference:  1.08420217248550443401e-19   0x8.00000000000000000000p-66
 ulp       :  1.0000
 max.ulp   :  0.0000
Maximal error of `expm1'
 is      : 1 ulp
 accepted: 0 ulp

Test suite completed:
  3618 test cases plus 3005 tests for exception flags executed.
  2 errors occurred.

elf/check-localplt.out:

--- ../scripts/data/localplt-i386-linux-gnu.data        2006-01-11 
21:06:19.000000000 +0000
+++ -   2008-11-30 20:52:09.962033876 +0000
@@ -1,4 +1,5 @@
 libc.so: _Unwind_Find_FDE
+libc.so: __bzero
 libc.so: calloc
 libc.so: free
 libc.so: malloc

(This looks like something missing from localplt-i386-linux-gnu.data to
me, not a bug.)

(Holes in test coverage: not tested with a GCC too old to support
-fstack-protector. Static testing not performed: see #7064.)

------- Additional Comment #3 From Nix 2008-12-04 00:55 -------
Created an attachment (id=3087)
stack protector support for glibc

This is posted at the request of Carlos O'Donell. TBH I don't care if it
doesn't go upstream, although given that it's already found a buffer overrun in
glibc I'd find that surprising. I'm more interested in distros picking it up.

(And 'never going to happen' is a peculiar statement. It has 'happened'. The
patch *exists*.)

------- Additional Comment #4 From Ryan S. Arnold 2008-12-10 17:09 -------
Nix

A failure in elf/check-localplt.out as indicated by a new symbol in
scripts/data/localplt-i386-linux-gnu.data means that libc proper is invoking the
new symbol via the plt when in-fact it should be making a direct invocation to a
libc internal symbol.  There are very few conditions under which this is allowed
(notably those cases where we allow libc functionality to be overridden).

I've looked through the code and it appears that the sunrpc code is the only
relevant code which uses __bzero.  I don't think there's an internal hidden
version of the symbol.  So these calls to __bzero probably shouldn't be there. 
Instead, they should use memset.  Or perhaps that patch which you're using uses
__bzero?

In order to verify, one can look at the symbol table:

objdump -DR libc.so > libc.dis

Search libc.dis for:

__bzero@plt

You should see a plt call stub, e.g.

00016198 <__bzero@plt>:
   16198:       ff a3 0c 00 00 00       jmp    *0xc(%ebx)
   1619e:       68 00 00 00 00          push   $0x0
   161a3:       e9 e0 ff ff ff          jmp    16188 <h_errno+0x16168>

Now search for: "call   16198"

call   16198 <__bzero@plt>

This should bring you to the disassembly of the function which invoked __bzero
via the PLT.  You can then go into the C source file and replace this with a
memset.  Do this for all calls to the address for __bzero.

------- Additional Comment #5 From Ryan S. Arnold 2008-12-10 18:51 -------
Here's a more thorough write-up of the same thing I just posted:

http://sources.redhat.com/glibc/wiki/Testing/Check-localplt

Invocation of __bzero() by the sunrpc code is acceptable since that code is in a
different library than libc.so so access via the PLT is expected.

------- Additional Comment #6 From Nix 2008-12-13 19:02 -------
Nice description, Ryan :)

A lot of the sunrpc code *does* land in libc (all the client code). Notably, 
bindresvport(), clnt_create(), clnt_broadcast(), universal() (called from 
registerrpc() via a callback from svc_register()), svctcp_create(), 
svcudp_bufcreate(), and key_gendes(), _des_crypt() (obviously used for 
DES-encrypted SunRPC), all explicitly call __bzero() and land in libc.

Almost certainly these would use memset() were the SunRPC code not ancient 
Sun-derived gunge with a 1986 copyright date...

------- Additional Comment #7 From Attila Tóth 2008-12-14 11:32 -------
Keep it going, guys.

To Ulrich Drepper:
How do you mean: "Never going to happen."?!

I always keen on people ignoring security measures.

Regards,
Dw.

------- Additional Comment #8 From Robert Connolly 2009-06-04 22:25 -------
I've been using a compromise. Glibc's programs can be compiled 
with -fstack-protector-all, or whatever other options you may want 
(-D_FORTIFY_SOURCE=2, -fPIE, etc), but not the libraries. I use the configparms 
file and set build-programs=no to build the libraries 
without -fstack-protector, then remove build-programs=no and add 'CFLAGS 
+= -fstack-protector-all' to configparms. No patches needed, test suites pass 
(remove -fstack-protector during the test suite), no crashes.

     Query page      Enter new bug
Actions: New | Query | bug # | Reports | Requests   New Account | Log In