diff options
author | 2017-10-10 22:53:53 +0200 | |
---|---|---|
committer | 2021-02-08 23:55:28 +0200 | |
commit | 7ca42fb2ec2fe50ad0130241daacebd9c1b9921e (patch) | |
tree | ffdd330ad070ede99994e37ab37ef315108173a5 | |
parent | Automatic date update in version.in (diff) | |
download | binutils-gdb-7ca42fb2ec2fe50ad0130241daacebd9c1b9921e.tar.gz binutils-gdb-7ca42fb2ec2fe50ad0130241daacebd9c1b9921e.tar.bz2 binutils-gdb-7ca42fb2ec2fe50ad0130241daacebd9c1b9921e.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)
-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 fdf0a174797..cad84a0739b 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -1333,6 +1333,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 927e0734bba..9d1b27c1333 100644 --- a/gold/options.h +++ b/gold/options.h @@ -1385,6 +1385,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 7b60d778587..37b8e9b6f6c 100644 --- a/ld/config.in +++ b/ld/config.in @@ -40,6 +40,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 b0969791959..0b8b606b851 100755 --- a/ld/configure +++ b/ld/configure @@ -828,6 +828,7 @@ with_lib_path enable_targets enable_64_bit_bfd with_sysroot +enable_poison_system_directories enable_gold enable_got enable_compressed_debug_sections @@ -1496,6 +1497,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) @@ -15841,7 +15844,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 c9c69ab9245..59dab0a6ac4 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. @@ -166,6 +166,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 7a602b9c6ab..e328be693cd 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -2810,6 +2810,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 81cb86d51e2..20df1fa0c9d 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -117,6 +117,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 b0101028321..9642bfc2538 100644 --- a/ld/ldlex.h +++ b/ld/ldlex.h @@ -146,6 +146,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 863df0293ea..bf21ddbe717 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -323,6 +323,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 f005a58a045..ac86459edd8 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -562,6 +562,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 }, @@ -1633,6 +1645,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), |