diff options
author | Mike Frysinger <vapier@gentoo.org> | 2015-05-25 04:42:58 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2017-03-03 11:03:18 -0700 |
commit | 9c3fda8166172bb9fa818bf2b7fec003847393d8 (patch) | |
tree | b75417ce654d435a8645a87ca0f17b5723d2155d | |
parent | bb101959912073f460669d75097215cde7b20019 (diff) | |
download | gdb-9c3fda8166172bb9fa818bf2b7fec003847393d8.zip gdb-9c3fda8166172bb9fa818bf2b7fec003847393d8.tar.gz gdb-9c3fda8166172bb9fa818bf2b7fec003847393d8.tar.bz2 |
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
-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.texinfo | 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 ed63b6f..5de289b 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -1285,6 +1285,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 a8b1d46..b7c725a 100644 --- a/gold/options.h +++ b/gold/options.h @@ -1344,6 +1344,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 2c6d698..d3cb7e8 100644 --- a/ld/config.in +++ b/ld/config.in @@ -17,6 +17,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 36af969..bd1d677 100755 --- a/ld/configure +++ b/ld/configure @@ -789,6 +789,7 @@ with_lib_path enable_targets enable_64_bit_bfd with_sysroot +enable_poison_system_directories enable_gold enable_got enable_compressed_debug_sections @@ -1446,6 +1447,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) @@ -15499,7 +15502,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 36a9f50..47f1d33 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -95,6 +95,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. @@ -172,6 +172,13 @@ typedef struct /* If set, display the target memory usage (per memory region). */ bfd_boolean print_memory_usage; + /* 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.texinfo b/ld/ld.texinfo index d393acdd..8eb156e 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -2403,6 +2403,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 0943bb2..b3bc224 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -114,6 +114,26 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) new_dirs->name = concat (ld_sysroot, name + 1, (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. */ @@ -141,6 +141,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_PRINT_MEMORY_USAGE, diff --git a/ld/ldmain.c b/ld/ldmain.c index f634eaa..bba1933 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 0b7d497..327b203 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -524,6 +524,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 }, @@ -1528,6 +1540,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), |