summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2015-05-25 04:42:58 -0400
committerMike Frysinger <vapier@gentoo.org>2017-03-03 11:03:18 -0700
commit9c3fda8166172bb9fa818bf2b7fec003847393d8 (patch)
treeb75417ce654d435a8645a87ca0f17b5723d2155d
parentbb101959912073f460669d75097215cde7b20019 (diff)
downloadbinutils-gdb-9c3fda8166172bb9fa818bf2b7fec003847393d8.tar.gz
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.cc33
-rw-r--r--gold/options.h7
-rw-r--r--ld/config.in3
-rwxr-xr-xld/configure14
-rw-r--r--ld/configure.ac10
-rw-r--r--ld/ld.h7
-rw-r--r--ld/ld.texinfo18
-rw-r--r--ld/ldfile.c20
-rw-r--r--ld/ldlex.h3
-rw-r--r--ld/ldmain.c7
-rw-r--r--ld/lexsup.c24
11 files changed, 146 insertions, 0 deletions
diff --git a/gold/options.cc b/gold/options.cc
index ed63b6f04fe..5de289b5dd2 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 a8b1d46aa10..b7c725a8253 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 2c6d698b6ce..d3cb7e882de 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 36af9695b1c..bd1d677e092 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 36a9f5083ae..47f1d33fa58 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.
diff --git a/ld/ld.h b/ld/ld.h
index 104bb8e2376..e1c3f744862 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -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 d393acdd940..8eb156efb8d 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 0943bb2dfa0..b3bc2246990 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. */
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 3ecac2bc865..7ed67bae3f2 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -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 f634eaa908a..bba193355b0 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 0b7d4976ac9..327b203eeb2 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),