* [Buildroot] [RFC 0/3] Hardening Wrapper Support
@ 2018-08-14 4:26 Matt Weber
2018-08-14 4:26 ` [Buildroot] [RFC 1/3] toolchain/toolchain-wrapper: add linker wrapper Matt Weber
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Matt Weber @ 2018-08-14 4:26 UTC (permalink / raw)
To: buildroot
I took an attempt at the start of the wrapper update. This is
still missing fortify and stack protector options being migrated.
I would assume these patches need cleanup as I was sloppy with the
linker wrapper including the relro stuff, but I wanted to get an
understanding of what I might have missed.
Matt Weber (3):
toolchain/toolchain-wrapper: add linker wrapper
hardening testing: busybox test case to verify linker wrapper behavior
with -r
toolchain/toolchain-wrapper: add BR2_RELRO_FULL support
package/gcc/gcc.mk | 7 +
support/testing/tests/core/test_hardening.py | 2 +-
.../toolchain-external/pkg-toolchain-external.mk | 3 +
toolchain/toolchain-wrapper-ld.c | 252 +++++++++++++++++++++
toolchain/toolchain-wrapper.c | 19 +-
toolchain/toolchain-wrapper.mk | 10 +
6 files changed, 291 insertions(+), 2 deletions(-)
create mode 100644 toolchain/toolchain-wrapper-ld.c
--
1.9.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Buildroot] [RFC 1/3] toolchain/toolchain-wrapper: add linker wrapper
2018-08-14 4:26 [Buildroot] [RFC 0/3] Hardening Wrapper Support Matt Weber
@ 2018-08-14 4:26 ` Matt Weber
2018-08-20 23:35 ` Matthew Weber
2018-08-14 4:26 ` [Buildroot] [RFC 2/3] hardening testing: busybox test case to verify linker wrapper behavior with -r Matt Weber
2018-08-14 4:26 ` [Buildroot] [RFC 3/3] toolchain/toolchain-wrapper: add BR2_RELRO_FULL support Matt Weber
2 siblings, 1 reply; 8+ messages in thread
From: Matt Weber @ 2018-08-14 4:26 UTC (permalink / raw)
To: buildroot
- Updates symlink creation int/ext toolchain
- Adds new source file for link wrapper with build/install
Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
---
package/gcc/gcc.mk | 7 +
.../toolchain-external/pkg-toolchain-external.mk | 3 +
toolchain/toolchain-wrapper-ld.c | 252 +++++++++++++++++++++
toolchain/toolchain-wrapper.mk | 10 +
4 files changed, 272 insertions(+)
create mode 100644 toolchain/toolchain-wrapper-ld.c
diff --git a/package/gcc/gcc.mk b/package/gcc/gcc.mk
index 1ae9b7e..a380004 100644
--- a/package/gcc/gcc.mk
+++ b/package/gcc/gcc.mk
@@ -334,6 +334,13 @@ define HOST_GCC_INSTALL_WRAPPER_AND_SIMPLE_SYMLINKS
ln -sf toolchain-wrapper $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}; \
ln -snf $$i.br_real $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}.br_real; \
;; \
+ *ld) \
+ rm -f $$i.br_real; \
+ mv $$i $$i.br_real; \
+ ln -sf toolchain-wrapper-ld $$i; \
+ ln -sf toolchain-wrapper-ld $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}; \
+ ln -snf $$i.br_real $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}.br_real; \
+ ;; \
*) \
ln -snf $$i $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}; \
;; \
diff --git a/toolchain/toolchain-external/pkg-toolchain-external.mk b/toolchain/toolchain-external/pkg-toolchain-external.mk
index 8b2c283..e4288bd 100644
--- a/toolchain/toolchain-external/pkg-toolchain-external.mk
+++ b/toolchain/toolchain-external/pkg-toolchain-external.mk
@@ -274,6 +274,9 @@ define TOOLCHAIN_EXTERNAL_INSTALL_WRAPPER
ln -sf $$(echo $$i | sed 's%^$(HOST_DIR)%..%') .; \
fi \
;; \
+ *ld) \
+ ln -sf toolchain-wrapper-ld $$base; \
+ ;; \
*) \
ln -sf $$(echo $$i | sed 's%^$(HOST_DIR)%..%') .; \
;; \
diff --git a/toolchain/toolchain-wrapper-ld.c b/toolchain/toolchain-wrapper-ld.c
new file mode 100644
index 0000000..384c571
--- /dev/null
+++ b/toolchain/toolchain-wrapper-ld.c
@@ -0,0 +1,252 @@
+/**
+ * Buildroot wrapper for toolchains. This simply executes the real toolchain
+ * with a number of arguments hardcoded, to ensure the toolchain uses the
+ * correct configuration.
+
+ * This file is based on the original wrapper code but updated for the linker.
+ *
+ * (C) 2011 Peter Korsgaard <jacmet@sunsite.dk>
+ * (C) 2011 Daniel Nystr?m <daniel.nystrom@timeterminal.se>
+ * (C) 2012 Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
+ * (C) 2013 Spenser Gilliland <spenser@gillilanding.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <stdbool.h>
+
+static char path[PATH_MAX];
+
+/**
+ * GCC linker errors out with certain combinations of arguments (examples are
+ * static/shared/r/pie, so we have to ensure that we only pass the predefined
+ * one to the real compiler if the inverse option isn't in the argument list.
+ * This specifies the worst case number of extra arguments we might pass
+ * Currently, we may have:
+ * -pie
+ */
+#define EXCLUSIVE_ARGS 1
+
+
+/* A {string,length} tuple, to avoid computing strlen() on constants.
+ * - str must be a \0-terminated string
+ * - len does not account for the terminating '\0'
+ */
+struct str_len_s {
+ const char *str;
+ size_t len;
+};
+
+/* Define a {string,length} tuple. Takes an unquoted constant string as
+ * parameter. sizeof() on a string literal includes the terminating \0,
+ * but we don't want to count it.
+ */
+#define STR_LEN(s) { #s, sizeof(#s)-1 }
+
+/* List of paths considered unsafe for cross-compilation.
+ *
+ * An unsafe path is one that points to a directory with libraries or
+ * headers for the build machine, which are not suitable for the target.
+ */
+static const struct str_len_s unsafe_paths[] = {
+ STR_LEN(/lib),
+ STR_LEN(/usr/include),
+ STR_LEN(/usr/lib),
+ STR_LEN(/usr/local/include),
+ STR_LEN(/usr/local/lib),
+ { NULL, 0 },
+};
+
+/* Unsafe options are options that specify a potentialy unsafe path,
+ * that will be checked by check_unsafe_path(), below.
+ */
+static const struct str_len_s unsafe_opts[] = {
+ STR_LEN(-I),
+ STR_LEN(-idirafter),
+ STR_LEN(-iquote),
+ STR_LEN(-isystem),
+ STR_LEN(-L),
+ { NULL, 0 },
+};
+
+/* Check if path is unsafe for cross-compilation. Unsafe paths are those
+ * pointing to the standard native include or library paths.
+ *
+ * We print the arguments leading to the failure. For some options, gcc
+ * accepts the path to be concatenated to the argument (e.g. -I/foo/bar)
+ * or separated (e.g. -I /foo/bar). In the first case, we need only print
+ * the argument as it already contains the path (arg_has_path), while in
+ * the second case we need to print both (!arg_has_path).
+ *
+ * If paranoid, exit in error instead of just printing a warning.
+ */
+static void check_unsafe_path(const char *arg,
+ const char *path,
+ int paranoid,
+ int arg_has_path)
+{
+ const struct str_len_s *p;
+
+ for (p=unsafe_paths; p->str; p++) {
+ if (strncmp(path, p->str, p->len))
+ continue;
+ fprintf(stderr,
+ "%s: %s: unsafe header/library path used in cross-compilation: '%s%s%s'\n",
+ program_invocation_short_name,
+ paranoid ? "ERROR" : "WARNING",
+ arg,
+ arg_has_path ? "" : "' '", /* close single-quote, space, open single-quote */
+ arg_has_path ? "" : path); /* so that arg and path are properly quoted. */
+ if (paranoid)
+ exit(1);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ char **args, **cur, **exec_args;
+ char *relbasedir, *absbasedir;
+ char *progpath = argv[0];
+ char *basename;
+ char *env_debug;
+ char *paranoid_wrapper;
+ int paranoid;
+ int ret, i, count = 0, debug;
+
+ /* Calculate the relative paths */
+ basename = strrchr(progpath, '/');
+ if (basename) {
+ *basename = '\0';
+ basename++;
+ relbasedir = malloc(strlen(progpath) + 7);
+ if (relbasedir == NULL) {
+ perror(__FILE__ ": malloc");
+ return 2;
+ }
+ sprintf(relbasedir, "%s/..", argv[0]);
+ absbasedir = realpath(relbasedir, NULL);
+ } else {
+ basename = progpath;
+ absbasedir = malloc(PATH_MAX + 1);
+ ret = readlink("/proc/self/exe", absbasedir, PATH_MAX);
+ if (ret < 0) {
+ perror(__FILE__ ": readlink");
+ return 2;
+ }
+ absbasedir[ret] = '\0';
+ for (i = ret; i > 0; i--) {
+ if (absbasedir[i] == '/') {
+ absbasedir[i] = '\0';
+ if (++count == 2)
+ break;
+ }
+ }
+ }
+ if (absbasedir == NULL) {
+ perror(__FILE__ ": realpath");
+ return 2;
+ }
+
+ /* Fill in the relative paths */
+#ifdef BR_CROSS_PATH_REL
+ ret = snprintf(path, sizeof(path), "%s/" BR_CROSS_PATH_REL "/%s" BR_CROSS_PATH_SUFFIX, absbasedir, basename);
+#elif defined(BR_CROSS_PATH_ABS)
+ ret = snprintf(path, sizeof(path), BR_CROSS_PATH_ABS "/%s" BR_CROSS_PATH_SUFFIX, basename);
+#else
+ ret = snprintf(path, sizeof(path), "%s/bin/%s" BR_CROSS_PATH_SUFFIX, absbasedir, basename);
+#endif
+ if (ret >= sizeof(path)) {
+ perror(__FILE__ ": overflow");
+ return 3;
+ }
+
+ cur = args = malloc((sizeof(char *) * (argc + EXCLUSIVE_ARGS)));
+ if (args == NULL) {
+ perror(__FILE__ ": malloc");
+ return 2;
+ }
+
+#ifdef BR2_RELRO_FULL
+ /* pie isn't compatible with static and shared/r accomplish the same thing */
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-static") ||
+ !strcmp(argv[i], "-shared") ||
+ !strcmp(argv[i], "-r"))
+ break;
+ }
+
+ if (i == argc)
+ *cur++ = "-pie";
+#endif
+
+ paranoid_wrapper = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH");
+ if (paranoid_wrapper && strlen(paranoid_wrapper) > 0)
+ paranoid = 1;
+ else
+ paranoid = 0;
+
+ /* Check for unsafe library and header paths */
+ for (i = 1; i < argc; i++) {
+ const struct str_len_s *opt;
+ for (opt=unsafe_opts; opt->str; opt++ ) {
+ /* Skip any non-unsafe option. */
+ if (strncmp(argv[i], opt->str, opt->len))
+ continue;
+
+ /* Handle both cases:
+ * - path is a separate argument,
+ * - path is concatenated with option.
+ */
+ if (argv[i][opt->len] == '\0') {
+ i++;
+ if (i == argc)
+ break;
+ check_unsafe_path(argv[i-1], argv[i], paranoid, 0);
+ } else
+ check_unsafe_path(argv[i], argv[i] + opt->len, paranoid, 1);
+ }
+ }
+
+ /* append forward args */
+ memcpy(cur, &argv[1], sizeof(char *) * (argc - 1));
+ cur += argc - 1;
+
+ /* finish with NULL termination */
+ *cur = NULL;
+
+ exec_args = args;
+
+ /* Debug the wrapper to see actual arguments passed to
+ * the compiler:
+ * unset, empty, or 0: do not trace
+ * set to 1 : trace all arguments on a single line
+ * set to 2 : trace one argument per line
+ */
+ if ((env_debug = getenv("BR2_DEBUG_WRAPPER"))) {
+ debug = atoi(env_debug);
+ if (debug > 0) {
+ fprintf(stderr, "Toolchain wrapper executing:");
+ for (i = 0; exec_args[i]; i++)
+ fprintf(stderr, "%s'%s'",
+ (debug == 2) ? "\n " : " ", exec_args[i]);
+ fprintf(stderr, "\n");
+ }
+ }
+
+ if (execv(exec_args[0], exec_args))
+ perror(path);
+
+ free(args);
+
+ return 2;
+}
diff --git a/toolchain/toolchain-wrapper.mk b/toolchain/toolchain-wrapper.mk
index b8074ef..19cd45d 100644
--- a/toolchain/toolchain-wrapper.mk
+++ b/toolchain/toolchain-wrapper.mk
@@ -45,14 +45,24 @@ ifeq ($(BR2_CCACHE_USE_BASEDIR),y)
TOOLCHAIN_WRAPPER_ARGS += -DBR_CCACHE_BASEDIR='"$(BASE_DIR)"'
endif
+ifeq ($(BR2_RELRO_FULL),y)
+TOOLCHAIN_WRAPPER_ARGS += -DBR2_RELRO_FULL
+endif
+
define TOOLCHAIN_WRAPPER_BUILD
$(HOSTCC) $(HOST_CFLAGS) $(TOOLCHAIN_WRAPPER_ARGS) \
-s -Wl,--hash-style=$(TOOLCHAIN_WRAPPER_HASH_STYLE) \
toolchain/toolchain-wrapper.c \
-o $(@D)/toolchain-wrapper
+ $(HOSTCC) $(HOST_CFLAGS) $(TOOLCHAIN_WRAPPER_ARGS) \
+ -s -Wl,--hash-style=$(TOOLCHAIN_WRAPPER_HASH_STYLE) \
+ toolchain/toolchain-wrapper-ld.c \
+ -o $(@D)/toolchain-wrapper-ld
endef
define TOOLCHAIN_WRAPPER_INSTALL
$(INSTALL) -D -m 0755 $(@D)/toolchain-wrapper \
$(HOST_DIR)/bin/toolchain-wrapper
+ $(INSTALL) -D -m 0755 $(@D)/toolchain-wrapper-ld \
+ $(HOST_DIR)/bin/toolchain-wrapper-ld
endef
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Buildroot] [RFC 2/3] hardening testing: busybox test case to verify linker wrapper behavior with -r
2018-08-14 4:26 [Buildroot] [RFC 0/3] Hardening Wrapper Support Matt Weber
2018-08-14 4:26 ` [Buildroot] [RFC 1/3] toolchain/toolchain-wrapper: add linker wrapper Matt Weber
@ 2018-08-14 4:26 ` Matt Weber
2018-08-21 7:10 ` Jan Kundrát
2018-08-14 4:26 ` [Buildroot] [RFC 3/3] toolchain/toolchain-wrapper: add BR2_RELRO_FULL support Matt Weber
2 siblings, 1 reply; 8+ messages in thread
From: Matt Weber @ 2018-08-14 4:26 UTC (permalink / raw)
To: buildroot
Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
---
support/testing/tests/core/test_hardening.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/support/testing/tests/core/test_hardening.py b/support/testing/tests/core/test_hardening.py
index fcec46f..ab8d078 100644
--- a/support/testing/tests/core/test_hardening.py
+++ b/support/testing/tests/core/test_hardening.py
@@ -21,7 +21,7 @@ class TestHardeningBase(infra.basetest.BRTest):
BR2_PACKAGE_HOST_CHECKSEC=y
# BR2_TARGET_ROOTFS_TAR is not set
"""
- checksec_files = ["usr/sbin/lighttpd"]
+ checksec_files = ["usr/sbin/lighttpd", "target/bin/busybox"]
def checksec_run(self, target_file):
filepath = os.path.join(self.builddir, "target", target_file)
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Buildroot] [RFC 3/3] toolchain/toolchain-wrapper: add BR2_RELRO_FULL support
2018-08-14 4:26 [Buildroot] [RFC 0/3] Hardening Wrapper Support Matt Weber
2018-08-14 4:26 ` [Buildroot] [RFC 1/3] toolchain/toolchain-wrapper: add linker wrapper Matt Weber
2018-08-14 4:26 ` [Buildroot] [RFC 2/3] hardening testing: busybox test case to verify linker wrapper behavior with -r Matt Weber
@ 2018-08-14 4:26 ` Matt Weber
2018-08-21 7:53 ` Jan Kundrát
2 siblings, 1 reply; 8+ messages in thread
From: Matt Weber @ 2018-08-14 4:26 UTC (permalink / raw)
To: buildroot
Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
---
toolchain/toolchain-wrapper.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/toolchain/toolchain-wrapper.c b/toolchain/toolchain-wrapper.c
index c5eb813..d36771c 100644
--- a/toolchain/toolchain-wrapper.c
+++ b/toolchain/toolchain-wrapper.c
@@ -49,8 +49,9 @@ static char _date_[sizeof("-D__DATE__=\"MMM DD YYYY\"")];
* -D__TIME__=
* -D__DATE__=
* -Wno-builtin-macro-redefined
+ * -fPIE
*/
-#define EXCLUSIVE_ARGS 6
+#define EXCLUSIVE_ARGS 7
static char *predef_args[] = {
#ifdef BR_CCACHE
@@ -363,6 +364,22 @@ int main(int argc, char **argv)
*cur++ = "-Wno-builtin-macro-redefined";
}
+#ifdef BR2_RELRO_FULL
+ /* Combinations of PIE and pic */
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-r") ||
+ !strcmp(argv[i], "-fpie") ||
+ !strcmp(argv[i], "-fPIE") ||
+ !strcmp(argv[i], "-fpic") ||
+ !strcmp(argv[i], "-fPIC") ||
+ !strcmp(argv[i], "-fno-pic"))
+ break;
+ }
+
+ if (i == argc)
+ *cur++ = "-fPIE";
+#endif
+
paranoid_wrapper = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH");
if (paranoid_wrapper && strlen(paranoid_wrapper) > 0)
paranoid = 1;
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Buildroot] [RFC 1/3] toolchain/toolchain-wrapper: add linker wrapper
2018-08-14 4:26 ` [Buildroot] [RFC 1/3] toolchain/toolchain-wrapper: add linker wrapper Matt Weber
@ 2018-08-20 23:35 ` Matthew Weber
0 siblings, 0 replies; 8+ messages in thread
From: Matthew Weber @ 2018-08-20 23:35 UTC (permalink / raw)
To: buildroot
All,
On Mon, Aug 13, 2018 at 11:26 PM Matt Weber
<matthew.weber@rockwellcollins.com> wrote:
>
> - Updates symlink creation int/ext toolchain
> - Adds new source file for link wrapper with build/install
>
> Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
> ---
> package/gcc/gcc.mk | 7 +
> .../toolchain-external/pkg-toolchain-external.mk | 3 +
> toolchain/toolchain-wrapper-ld.c | 252 +++++++++++++++++++++
> toolchain/toolchain-wrapper.mk | 10 +
> 4 files changed, 272 insertions(+)
> create mode 100644 toolchain/toolchain-wrapper-ld.c
>
> diff --git a/package/gcc/gcc.mk b/package/gcc/gcc.mk
> index 1ae9b7e..a380004 100644
> --- a/package/gcc/gcc.mk
> +++ b/package/gcc/gcc.mk
> @@ -334,6 +334,13 @@ define HOST_GCC_INSTALL_WRAPPER_AND_SIMPLE_SYMLINKS
> ln -sf toolchain-wrapper $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}; \
> ln -snf $$i.br_real $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}.br_real; \
> ;; \
> + *ld) \
> + rm -f $$i.br_real; \
> + mv $$i $$i.br_real; \
> + ln -sf toolchain-wrapper-ld $$i; \
> + ln -sf toolchain-wrapper-ld $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}; \
> + ln -snf $$i.br_real $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}.br_real; \
> + ;; \
> *) \
> ln -snf $$i $(ARCH)-linux$${i##$(GNU_TARGET_NAME)}; \
> ;; \
> diff --git a/toolchain/toolchain-external/pkg-toolchain-external.mk b/toolchain/toolchain-external/pkg-toolchain-external.mk
> index 8b2c283..e4288bd 100644
> --- a/toolchain/toolchain-external/pkg-toolchain-external.mk
> +++ b/toolchain/toolchain-external/pkg-toolchain-external.mk
> @@ -274,6 +274,9 @@ define TOOLCHAIN_EXTERNAL_INSTALL_WRAPPER
> ln -sf $$(echo $$i | sed 's%^$(HOST_DIR)%..%') .; \
> fi \
> ;; \
> + *ld) \
> + ln -sf toolchain-wrapper-ld $$base; \
> + ;; \
> *) \
> ln -sf $$(echo $$i | sed 's%^$(HOST_DIR)%..%') .; \
> ;; \
> diff --git a/toolchain/toolchain-wrapper-ld.c b/toolchain/toolchain-wrapper-ld.c
> new file mode 100644
> index 0000000..384c571
> --- /dev/null
> +++ b/toolchain/toolchain-wrapper-ld.c
> @@ -0,0 +1,252 @@
> +/**
> + * Buildroot wrapper for toolchains. This simply executes the real toolchain
> + * with a number of arguments hardcoded, to ensure the toolchain uses the
> + * correct configuration.
> +
> + * This file is based on the original wrapper code but updated for the linker.
> + *
> + * (C) 2011 Peter Korsgaard <jacmet@sunsite.dk>
> + * (C) 2011 Daniel Nystr?m <daniel.nystrom@timeterminal.se>
> + * (C) 2012 Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
> + * (C) 2013 Spenser Gilliland <spenser@gillilanding.com>
> + *
> + * This file is licensed under the terms of the GNU General Public License
> + * version 2. This program is licensed "as is" without any warranty of any
> + * kind, whether express or implied.
> + */
> +
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <string.h>
> +#include <limits.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +#include <time.h>
> +#include <stdbool.h>
> +
> +static char path[PATH_MAX];
> +
> +/**
> + * GCC linker errors out with certain combinations of arguments (examples are
> + * static/shared/r/pie, so we have to ensure that we only pass the predefined
> + * one to the real compiler if the inverse option isn't in the argument list.
> + * This specifies the worst case number of extra arguments we might pass
> + * Currently, we may have:
> + * -pie
> + */
> +#define EXCLUSIVE_ARGS 1
> +
> +
> +/* A {string,length} tuple, to avoid computing strlen() on constants.
> + * - str must be a \0-terminated string
> + * - len does not account for the terminating '\0'
> + */
> +struct str_len_s {
> + const char *str;
> + size_t len;
> +};
> +
> +/* Define a {string,length} tuple. Takes an unquoted constant string as
> + * parameter. sizeof() on a string literal includes the terminating \0,
> + * but we don't want to count it.
> + */
> +#define STR_LEN(s) { #s, sizeof(#s)-1 }
> +
> +/* List of paths considered unsafe for cross-compilation.
> + *
> + * An unsafe path is one that points to a directory with libraries or
> + * headers for the build machine, which are not suitable for the target.
> + */
> +static const struct str_len_s unsafe_paths[] = {
> + STR_LEN(/lib),
> + STR_LEN(/usr/include),
> + STR_LEN(/usr/lib),
> + STR_LEN(/usr/local/include),
> + STR_LEN(/usr/local/lib),
> + { NULL, 0 },
> +};
> +
> +/* Unsafe options are options that specify a potentialy unsafe path,
> + * that will be checked by check_unsafe_path(), below.
> + */
> +static const struct str_len_s unsafe_opts[] = {
> + STR_LEN(-I),
> + STR_LEN(-idirafter),
> + STR_LEN(-iquote),
> + STR_LEN(-isystem),
> + STR_LEN(-L),
> + { NULL, 0 },
> +};
> +
> +/* Check if path is unsafe for cross-compilation. Unsafe paths are those
> + * pointing to the standard native include or library paths.
> + *
> + * We print the arguments leading to the failure. For some options, gcc
> + * accepts the path to be concatenated to the argument (e.g. -I/foo/bar)
> + * or separated (e.g. -I /foo/bar). In the first case, we need only print
> + * the argument as it already contains the path (arg_has_path), while in
> + * the second case we need to print both (!arg_has_path).
> + *
> + * If paranoid, exit in error instead of just printing a warning.
> + */
> +static void check_unsafe_path(const char *arg,
> + const char *path,
> + int paranoid,
> + int arg_has_path)
I left unsafe path checking in as I assumed the -L searchdir could
still be specified when the linker is invoked.
Matt
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Buildroot] [RFC 2/3] hardening testing: busybox test case to verify linker wrapper behavior with -r
2018-08-14 4:26 ` [Buildroot] [RFC 2/3] hardening testing: busybox test case to verify linker wrapper behavior with -r Matt Weber
@ 2018-08-21 7:10 ` Jan Kundrát
0 siblings, 0 replies; 8+ messages in thread
From: Jan Kundrát @ 2018-08-21 7:10 UTC (permalink / raw)
To: buildroot
On ?ter? 14. srpna 2018 6:26:42 CEST, Matt Weber wrote:
> Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
> ---
> support/testing/tests/core/test_hardening.py | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/support/testing/tests/core/test_hardening.py
> b/support/testing/tests/core/test_hardening.py
> index fcec46f..ab8d078 100644
> --- a/support/testing/tests/core/test_hardening.py
> +++ b/support/testing/tests/core/test_hardening.py
> @@ -21,7 +21,7 @@ class TestHardeningBase(infra.basetest.BRTest):
> BR2_PACKAGE_HOST_CHECKSEC=y
> # BR2_TARGET_ROOTFS_TAR is not set
> """
> - checksec_files = ["usr/sbin/lighttpd"]
> + checksec_files = ["usr/sbin/lighttpd", "target/bin/busybox"]
>
> def checksec_run(self, target_file):
> filepath = os.path.join(self.builddir, "target", target_file)
This patch does not apply to neither master nor next for me because there's
no support/testing/tests/core/test_hardening.py in there.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Buildroot] [RFC 3/3] toolchain/toolchain-wrapper: add BR2_RELRO_FULL support
2018-08-14 4:26 ` [Buildroot] [RFC 3/3] toolchain/toolchain-wrapper: add BR2_RELRO_FULL support Matt Weber
@ 2018-08-21 7:53 ` Jan Kundrát
2018-08-21 12:40 ` Matthew Weber
0 siblings, 1 reply; 8+ messages in thread
From: Jan Kundrát @ 2018-08-21 7:53 UTC (permalink / raw)
To: buildroot
On ?ter? 14. srpna 2018 6:26:43 CEST, Matt Weber wrote:
> Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
> ---
> toolchain/toolchain-wrapper.c | 19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/toolchain/toolchain-wrapper.c b/toolchain/toolchain-wrapper.c
> index c5eb813..d36771c 100644
> --- a/toolchain/toolchain-wrapper.c
> +++ b/toolchain/toolchain-wrapper.c
> @@ -49,8 +49,9 @@ static char _date_[sizeof("-D__DATE__=\"MMM DD YYYY\"")];
> * -D__TIME__=
> * -D__DATE__=
> * -Wno-builtin-macro-redefined
> + * -fPIE
nit: this looks like a whitespace error (one too many spaces)
> */
> -#define EXCLUSIVE_ARGS 6
> +#define EXCLUSIVE_ARGS 7
>
> static char *predef_args[] = {
> #ifdef BR_CCACHE
> @@ -363,6 +364,22 @@ int main(int argc, char **argv)
> *cur++ = "-Wno-builtin-macro-redefined";
> }
>
> +#ifdef BR2_RELRO_FULL
> + /* Combinations of PIE and pic */
> + for (i = 1; i < argc; i++) {
> + if (!strcmp(argv[i], "-r") ||
> + !strcmp(argv[i], "-fpie") ||
> + !strcmp(argv[i], "-fPIE") ||
> + !strcmp(argv[i], "-fpic") ||
> + !strcmp(argv[i], "-fPIC") ||
> + !strcmp(argv[i], "-fno-pic"))
> + break;
> + }
> +
> + if (i == argc)
> + *cur++ = "-fPIE";
> +#endif
> +
> paranoid_wrapper = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH");
> if (paranoid_wrapper && strlen(paranoid_wrapper) > 0)
> paranoid = 1;
I needed some more patches to build with the following hardening settings:
BR2_SSP_STRONG=y
BR2_RELRO_FULL=y
BR2_FORTIFY_SOURCE_2=y
- https://patchwork.ozlabs.org/patch/865166/
- https://patchwork.ozlabs.org/patch/865168/ (this one need changes so that
it touches packages/libzlib/ now)
Then my build failed when building util-linux, see the attached log.
Cheers,
Jan
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: bug-util-linux
URL: <http://lists.busybox.net/pipermail/buildroot/attachments/20180821/9a27f542/attachment.ksh>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Buildroot] [RFC 3/3] toolchain/toolchain-wrapper: add BR2_RELRO_FULL support
2018-08-21 7:53 ` Jan Kundrát
@ 2018-08-21 12:40 ` Matthew Weber
0 siblings, 0 replies; 8+ messages in thread
From: Matthew Weber @ 2018-08-21 12:40 UTC (permalink / raw)
To: buildroot
Jan,
On Tue, Aug 21, 2018 at 2:53 AM Jan Kundr?t <jan.kundrat@cesnet.cz> wrote:
>
> On ?ter? 14. srpna 2018 6:26:43 CEST, Matt Weber wrote:
> > Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
> > ---
> > toolchain/toolchain-wrapper.c | 19 ++++++++++++++++++-
> > 1 file changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/toolchain/toolchain-wrapper.c b/toolchain/toolchain-wrapper.c
> > index c5eb813..d36771c 100644
> > --- a/toolchain/toolchain-wrapper.c
> > +++ b/toolchain/toolchain-wrapper.c
> > @@ -49,8 +49,9 @@ static char _date_[sizeof("-D__DATE__=\"MMM DD YYYY\"")];
> > * -D__TIME__=
> > * -D__DATE__=
> > * -Wno-builtin-macro-redefined
> > + * -fPIE
>
> nit: this looks like a whitespace error (one too many spaces)
>
> > */
> > -#define EXCLUSIVE_ARGS 6
> > +#define EXCLUSIVE_ARGS 7
> >
> > static char *predef_args[] = {
> > #ifdef BR_CCACHE
> > @@ -363,6 +364,22 @@ int main(int argc, char **argv)
> > *cur++ = "-Wno-builtin-macro-redefined";
> > }
> >
> > +#ifdef BR2_RELRO_FULL
> > + /* Combinations of PIE and pic */
> > + for (i = 1; i < argc; i++) {
> > + if (!strcmp(argv[i], "-r") ||
> > + !strcmp(argv[i], "-fpie") ||
> > + !strcmp(argv[i], "-fPIE") ||
> > + !strcmp(argv[i], "-fpic") ||
> > + !strcmp(argv[i], "-fPIC") ||
> > + !strcmp(argv[i], "-fno-pic"))
> > + break;
> > + }
> > +
> > + if (i == argc)
> > + *cur++ = "-fPIE";
> > +#endif
> > +
> > paranoid_wrapper = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH");
> > if (paranoid_wrapper && strlen(paranoid_wrapper) > 0)
> > paranoid = 1;
>
> I needed some more patches to build with the following hardening settings:
>
> BR2_SSP_STRONG=y
> BR2_RELRO_FULL=y
> BR2_FORTIFY_SOURCE_2=y
>
> - https://patchwork.ozlabs.org/patch/865166/
> - https://patchwork.ozlabs.org/patch/865168/ (this one need changes so that
> it touches packages/libzlib/ now)
>
> Then my build failed when building util-linux, see the attached log.
Thanks for the feedback. Sorry this topic has some loose ends at this
point with a couple un-applied patches and this RFC.
I'll send out a full patchset this week once I get past some
external/internal toolchain symlnk issues with *.br_real.
If you wouldn't mind sharing your defconfig, I'll give it a test
before I sent out the next series.
Matt
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-08-21 12:40 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-14 4:26 [Buildroot] [RFC 0/3] Hardening Wrapper Support Matt Weber
2018-08-14 4:26 ` [Buildroot] [RFC 1/3] toolchain/toolchain-wrapper: add linker wrapper Matt Weber
2018-08-20 23:35 ` Matthew Weber
2018-08-14 4:26 ` [Buildroot] [RFC 2/3] hardening testing: busybox test case to verify linker wrapper behavior with -r Matt Weber
2018-08-21 7:10 ` Jan Kundrát
2018-08-14 4:26 ` [Buildroot] [RFC 3/3] toolchain/toolchain-wrapper: add BR2_RELRO_FULL support Matt Weber
2018-08-21 7:53 ` Jan Kundrát
2018-08-21 12:40 ` Matthew Weber
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.