https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88590

            Bug ID: 88590
           Summary: System Integrity Protection (SIP) breaks GCC build
                    assumptions on Darwin.
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: bootstrap
          Assignee: unassigned at gcc dot gnu.org
          Reporter: iains at gcc dot gnu.org
  Target Milestone: ---

Synopsis:

macOS from 10.11 (darwin15) has a new measure of default system protection,
where there is no "root" access to certain parts of the system (e.g. /usr etc.)
and executables are protected from dynamic loader exploits - such as
interposing unauthorised libraries using "DYLD_LIBARRY_PATH" (Darwin's
equivalent of LD_LIBRARY_PATH).

Unfortunately, GCC's build and test environment relies on using
DYLD_LIBRARY_PATH to point to the uninstalled libraries just built by the
toolchain (these might even be needed during the actual build).

So, when SIP is enabled (the default), DYLD_xxx are silently ignored. By dumb
luck mostly we are succeeding with builds - this is because the compiler is
built with statically-linked libstdc++ & libgcc (technically the latter fires
another problem, related to incorrect unwinder usage, but let's put that to one
side, since GCC is not supposed to use exceptions).

Unprotected executables (e.g. the ones we build and the test suite exes) can
use DYLD_LIBRARY_PATH so 

DYLD_LIBRARY_PATH=somewhere/with/a/test/library ./foo 

will work.

But
export DYLD_LIBRARY_PATH=somewhere/with/a/test/library

will not work, because that uses a "protected" binary (/use/bin/bash).

So .. I think that one needs to do

make install-target && make check.

To get meaningful test results with SIP enabled 

even so, the behaviour of configure tests might be suspect, if the result would
depend on a built library rather than one installed on the system.

===== What to do?

(non)-Fix 
=========

Disable SIP.

This is not something we should be requiring - it's not really acceptable for
the toolchain build to force reduction in system security measures.  However,
Apple provides a mechanism for switching SIP off and when that is done
DYLD_LIBRARY_PATH works again [and we then fire up PR84257 (since the handling
of DYLD_LIBRARY_PATH with SIP switched off seems to be very slow)].

Possible fix #1
===============

This is what I've been tinkering with

1) convert all the target libraries to use @rpath/libxxxxx.dylib as their
install names
2) get GCC to emit the necessary rpaths into executables during build and test
(and, obviously, at install time).

Actually, this is sensibly in line with a useful macOS deployment model - since
the "approved" way to package shared libraries on macOS / Darwin is to place
them alongside the executables and use rpaths.

unfortunately:
 * it's quite an involved set of changes and almost certainly not going to
happen for 9.
 * there are details to work out to make sure that build-time paths don't leak
into installed libraries/exes.

Possible fix #2
===============

Have a build environment where all the used executables and paths are outside
the remit of SIP.  This is untested so far, and might not suit the casual user
of GCC - since it would involve building at least a shell / make / GCC
prerequisites etc.

Reply via email to