diff options
author | Mike Frysinger <vapier@gentoo.org> | 2017-10-10 22:53:53 +0200 |
---|---|---|
committer | Andreas K. Hüttel <dilfridge@gentoo.org> | 2019-10-13 05:48:01 +0200 |
commit | 99d549d66357bbe3a1377f263f3968edd01acc7a (patch) | |
tree | bfcac8f083ce96eb2767b63a5c94a077fd7c077d | |
parent | Gentoo: Add an option --no-warn-shared-textrel (self-explanatory) (diff) | |
download | binutils-gdb-99d549d66357bbe3a1377f263f3968edd01acc7a.tar.gz binutils-gdb-99d549d66357bbe3a1377f263f3968edd01acc7a.tar.bz2 binutils-gdb-99d549d66357bbe3a1377f263f3968edd01acc7a.zip |
Gentoo: gold/ld: add support for poisoned system directories
This is based on the old CodeSourcery patch written by Joseph Myers to add
support to the link for detecting & rejecting bad -L paths when using a
cross-compiler. The differences here:
* The command line flags are always available.
* We can turn on & off the warning via the command line.
* The configure option controls the default warning behavior.
* Add support for gold.
It is not currently upstream, nor has it been submitted at all. There are
no plans to do so currently either.
BUG=chromium:488360
TEST=`cbuildbot chromiumos-sdk` passes # tests arm/amd64/mipsel/x86
TEST=`cbuildbot panther_moblab-full whirlwind-release` pass
TEST=`cbuildbot {x32,arm64}-generic-full` has no new failures
TEST=x86_64-cros-linux-gnu-ld throws warnings when using -L/lib (gold & bfd)
Reviewed-on: https://chromium-review.googlesource.com/272083
(cherry picked from commit f92dbf35c00ab13cee36f6be8ae5ca46454d9000)
(cherry picked from commit bcf3dcf1c50ff2a9368cd74f377d4c0657324246)
-rw-r--r-- | gold/options.cc | 33 | ||||
-rw-r--r-- | gold/options.h | 7 | ||||
-rw-r--r-- | ld/config.in | 3 | ||||
-rwxr-xr-x | ld/configure | 14 | ||||
-rw-r--r-- | ld/configure.ac | 10 | ||||
-rw-r--r-- | ld/ld.h | 7 | ||||
-rw-r--r-- | ld/ld.texi | 18 | ||||
-rw-r--r-- | ld/ldfile.c | 20 | ||||
-rw-r--r-- | ld/ldlex.h | 3 | ||||
-rw-r--r-- | ld/ldmain.c | 7 | ||||
-rw-r--r-- | ld/lexsup.c | 24 |
11 files changed, 146 insertions, 0 deletions
diff --git a/gold/options.cc b/gold/options.cc index d92394120a5..d221a012c49 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -1290,6 +1290,39 @@ General_options::finalize() // in the path, as appropriate. this->add_sysroot(); + // Now check if library_path is poisoned. + if (this->warn_poison_system_directories()) + { + std::vector<std::string> bad_paths; + + bad_paths.push_back("/lib"); + // TODO: This check is disabled for now due to a bunch of packages that + // use libtool and relink with -L/usr/lib paths (albeit after the right + // sysroot path). Once those are fixed we can enable. + // We also need to adjust it so it only rejects one or two levels deep. + // Gcc's internal paths also live below /usr/lib. + // http://crbug.com/488360 + // bad_paths.push_back("/usr/lib"); + bad_paths.push_back("/usr/local/lib"); + bad_paths.push_back("/usr/X11R6/lib"); + + for (std::vector<std::string>::const_iterator b = bad_paths.begin(); + b != bad_paths.end(); + ++b) + for (Dir_list::iterator p = this->library_path_.value.begin(); + p != this->library_path_.value.end(); + ++p) + if (!p->name().compare(0, b->size(), *b)) + { + if (this->error_poison_system_directories()) + gold_fatal(_("library search path \"%s\" is unsafe for " + "cross-compilation"), p->name().c_str()); + else + gold_warning(_("library search path \"%s\" is unsafe for " + "cross-compilation"), p->name().c_str()); + } + } + // Now that we've normalized the options, check for contradictory ones. if (this->shared() && this->is_static()) gold_fatal(_("-shared and -static are incompatible")); diff --git a/gold/options.h b/gold/options.h index f7c127953c2..f0fdcb1fc11 100644 --- a/gold/options.h +++ b/gold/options.h @@ -1375,6 +1375,13 @@ class General_options DEFINE_bool(warn_multiple_gp, options::TWO_DASHES, '\0', false, N_("Ignored"), NULL); + DEFINE_bool(warn_poison_system_directories, options::TWO_DASHES, '\0', false, + N_("Warn for -L options using system directories"), + N_("Do not warn for -L options using system directories")); + DEFINE_bool(error_poison_system_directories, options::TWO_DASHES, '\0', false, + N_("Give an error for -L options using system directories"), + NULL); + DEFINE_bool(warn_search_mismatch, options::TWO_DASHES, '\0', true, N_("Warn when skipping an incompatible library"), N_("Don't warn when skipping an incompatible library")); diff --git a/ld/config.in b/ld/config.in index d93c9b08300..5da2742beac 100644 --- a/ld/config.in +++ b/ld/config.in @@ -31,6 +31,9 @@ language is requested. */ #undef ENABLE_NLS +/* Define to warn for use of native system library directories */ +#undef ENABLE_POISON_SYSTEM_DIRECTORIES + /* Additional extension a shared object might have. */ #undef EXTRA_SHLIB_EXTENSION diff --git a/ld/configure b/ld/configure index b532ef94fa2..65d12cbf883 100755 --- a/ld/configure +++ b/ld/configure @@ -823,6 +823,7 @@ with_lib_path enable_targets enable_64_bit_bfd with_sysroot +enable_poison_system_directories enable_gold enable_got enable_compressed_debug_sections @@ -1487,6 +1488,8 @@ Optional Features: --disable-largefile omit support for large files --enable-targets alternative target configurations --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) + --enable-poison-system-directories + warn for use of native system library directories --enable-gold[=ARG] build gold [ARG={default,yes,no}] --enable-got=<type> GOT handling scheme (target, single, negative, multigot) @@ -15804,7 +15807,18 @@ else fi +# Check whether --enable-poison-system-directories was given. +if test "${enable_poison_system_directories+set}" = set; then : + enableval=$enable_poison_system_directories; +else + enable_poison_system_directories=no +fi + +if test "x${enable_poison_system_directories}" = "xyes"; then +$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h + +fi # Check whether --enable-got was given. if test "${enable_got+set}" = set; then : diff --git a/ld/configure.ac b/ld/configure.ac index ee62d10ac58..bc3e14e729d 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -94,6 +94,16 @@ AC_SUBST(use_sysroot) AC_SUBST(TARGET_SYSTEM_ROOT) AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) +AC_ARG_ENABLE([poison-system-directories], + AS_HELP_STRING([--enable-poison-system-directories], + [warn for use of native system library directories]),, + [enable_poison_system_directories=no]) +if test "x${enable_poison_system_directories}" = "xyes"; then + AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], + [1], + [Define to warn for use of native system library directories]) +fi + dnl Use --enable-gold to decide if this linker should be the default. dnl "install_as_default" is set to false if gold is the default linker. dnl "installed_linker" is the installed BFD linker name. @@ -180,6 +180,13 @@ typedef struct in the linker script. */ bfd_boolean force_group_allocation; + /* If TRUE warn for uses of system directories when cross linking. */ + bfd_boolean warn_poison_system_directories; + + /* If TRUE (default FALSE) give an error for uses of system + directories when cross linking instead of a warning. */ + bfd_boolean error_poison_system_directories; + /* Big or little endian as set on command line. */ enum endian_enum endian; diff --git a/ld/ld.texi b/ld/ld.texi index ad2537454c1..91886f0d68b 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -2561,6 +2561,24 @@ string identifying the original linked file does not change. Passing @code{none} for @var{style} disables the setting from any @code{--build-id} options earlier on the command line. + +@kindex --warn-poison-system-directories +@item --warn-poison-system-directories +Warn for @option{-L} options using system directories such as +@file{/usr/lib} when cross linking. This option is intended for use +in environments that want to detect and reject incorrect link settings. + +@kindex --no-warn-poison-system-directories +@item --no-warn-poison-system-directories +Do not warn for @option{-L} options using system directories such as +@file{/usr/lib} when cross linking. This option is intended for use +in chroot environments when such directories contain the correct +libraries for the target system rather than the host. + +@kindex --error-poison-system-directories +@item --error-poison-system-directories +Give an error instead of a warning for @option{-L} options using +system directories when cross linking. @end table @c man end diff --git a/ld/ldfile.c b/ld/ldfile.c index 7f60319390e..baf736f8223 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -116,6 +116,26 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) new_dirs->name = concat (ld_sysroot, name + strlen ("$SYSROOT"), (const char *) NULL); else new_dirs->name = xstrdup (name); + + if (command_line.warn_poison_system_directories + && (!strncmp (name, "/lib", 4) + /* TODO: This check is disabled for now due to a bunch of packages that + * use libtool and relink with -L/usr/lib paths (albeit after the right + * sysroot path). Once those are fixed we can enable. + * We also need to adjust it so it only rejects one or two levels deep. + * Gcc's internal paths also live below /usr/lib. + * http://crbug.com/488360 */ + /* || !strncmp (name, "/usr/lib", 8) */ + || !strncmp (name, "/usr/local/lib", 14) + || !strncmp (name, "/usr/X11R6/lib", 14))) + { + if (command_line.error_poison_system_directories) + einfo (_("%X%P: error: library search path \"%s\" is unsafe for " + "cross-compilation\n"), name); + else + einfo (_("%P: warning: library search path \"%s\" is unsafe for " + "cross-compilation\n"), name); + } } /* Try to open a BFD for a lang_input_statement. */ diff --git a/ld/ldlex.h b/ld/ldlex.h index 96f88bc3651..c15e8818127 100644 --- a/ld/ldlex.h +++ b/ld/ldlex.h @@ -142,6 +142,9 @@ enum option_values OPTION_PRINT_OUTPUT_FORMAT, OPTION_PRINT_SYSROOT, OPTION_IGNORE_UNRESOLVED_SYMBOL, + OPTION_WARN_POISON_SYSTEM_DIRECTORIES, + OPTION_NO_WARN_POISON_SYSTEM_DIRECTORIES, + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, OPTION_PUSH_STATE, OPTION_POP_STATE, OPTION_DISABLE_MULTIPLE_DEFS_ABS, diff --git a/ld/ldmain.c b/ld/ldmain.c index 335334444b0..6f3cbe293eb 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -270,6 +270,13 @@ main (int argc, char **argv) command_line.warn_mismatch = TRUE; command_line.warn_search_mismatch = TRUE; command_line.check_section_addresses = -1; + command_line.warn_poison_system_directories = +#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES + TRUE; +#else + FALSE; +#endif + command_line.error_poison_system_directories = FALSE; /* We initialize DEMANGLING based on the environment variable COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the diff --git a/ld/lexsup.c b/ld/lexsup.c index a6c72b9e3be..68fff8e9343 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -535,6 +535,18 @@ static const struct ld_option ld_options[] = OPTION_IGNORE_UNRESOLVED_SYMBOL}, '\0', N_("SYMBOL"), N_("Unresolved SYMBOL will not cause an error or warning"), TWO_DASHES }, + { {"warn-poison-system-directories", no_argument, NULL, + OPTION_WARN_POISON_SYSTEM_DIRECTORIES}, + '\0', NULL, N_("Warn for -L options using system directories"), + TWO_DASHES }, + { {"no-warn-poison-system-directories", no_argument, NULL, + OPTION_NO_WARN_POISON_SYSTEM_DIRECTORIES}, + '\0', NULL, N_("Do not warn for -L options using system directories"), + TWO_DASHES }, + { {"error-poison-system-directories", no_argument, NULL, + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, + '\0', NULL, N_("Give an error for -L options using system directories"), + TWO_DASHES }, { {"push-state", no_argument, NULL, OPTION_PUSH_STATE}, '\0', NULL, N_("Push state of flags governing input file handling"), TWO_DASHES }, @@ -1555,6 +1567,18 @@ parse_args (unsigned argc, char **argv) } break; + case OPTION_WARN_POISON_SYSTEM_DIRECTORIES: + command_line.warn_poison_system_directories = TRUE; + break; + + case OPTION_NO_WARN_POISON_SYSTEM_DIRECTORIES: + command_line.warn_poison_system_directories = FALSE; + break; + + case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: + command_line.error_poison_system_directories = TRUE; + break; + case OPTION_PUSH_STATE: input_flags.pushed = xmemdup (&input_flags, sizeof (input_flags), |