From 2b69f168a6847885233e88be02a1143a4c55b59f Mon Sep 17 00:00:00 2001 From: LiFeng Date: Wed, 15 Apr 2020 18:58:24 +0800 Subject: [PATCH 33/49] build: add secure build flags Signed-off-by: LiFeng --- configure.ac | 14 +++++- src/lxc/Makefile.am | 8 +++- src/lxc/cgroups/cgfsng.c | 117 ++++++++++++++++++++++++--------------------- src/lxc/confile.c | 1 - src/lxc/terminal.c | 6 ++- src/lxc/tools/lxc_attach.c | 2 - src/lxc/utils.c | 7 +++ 7 files changed, 93 insertions(+), 62 deletions(-) diff --git a/configure.ac b/configure.ac index 56d0cb7..438d292 100644 --- a/configure.ac +++ b/configure.ac @@ -43,6 +43,7 @@ AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability subdir-objects]) AC_CANONICAL_HOST AM_PROG_CC_C_O AC_USE_SYSTEM_EXTENSIONS +CFLAGS=`echo "${CFLAGS#\-g}"` # Test if we have a new enough compiler. AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @@ -190,6 +191,11 @@ AC_ARG_ENABLE([werror], [AS_HELP_STRING([--disable-werror], [do not treat warnings as errors])], [enable_werror=$enableval], [enable_werror=yes]) +AC_ARG_ENABLE([debug], + [AC_HELP_STRING([--enable-debug], + [set -g into cflags [default=no]])], + [], [enable_debug=no]) + # Allow disabling rpath AC_ARG_ENABLE([rpath], [AS_HELP_STRING([--enable-rpath], [set rpath in executables [default=no]])], @@ -732,7 +738,6 @@ AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing], [CFLAGS="$CFLAGS -fno-strict-alias AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [CFLAGS="$CFLAGS -fstack-clash-protection"],,[-Werror]) AX_CHECK_LINK_FLAG([-fstack-protector-strong], [CFLAGS="$CFLAGS -fstack-protector-strong"],,[-Werror]) AX_CHECK_LINK_FLAG([--param=ssp-buffer-size=4], [CFLAGS="$CFLAGS --param=ssp-buffer-size=4"],,[-Werror]) -AX_CHECK_COMPILE_FLAG([-g], [CFLAGS="$CFLAGS -g"],,[-Werror]) AX_CHECK_COMPILE_FLAG([--mcet -fcf-protection], [CFLAGS="$CFLAGS --mcet -fcf-protection"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Werror=implicit-function-declaration], [CFLAGS="$CFLAGS -Werror=implicit-function-declaration"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Wlogical-op], [CFLAGS="$CFLAGS -Wlogical-op"],,[-Werror]) @@ -759,12 +764,17 @@ AX_CHECK_COMPILE_FLAG([-fexceptions], [CFLAGS="$CFLAGS -fexceptions"],,[-Werror] AX_CHECK_LINK_FLAG([-z relro], [LDFLAGS="$LDFLAGS -z relro"],,[]) AX_CHECK_LINK_FLAG([-z now], [LDFLAGS="$LDFLAGS -z now"],,[]) +AX_CHECK_LINK_FLAG([-z noexecstack], [LDFLAGS="$LDFLAGS -z noexecstack"],,[]) -CFLAGS="$CFLAGS -Wvla -std=gnu11" +CFLAGS="$CFLAGS -Wvla -std=gnu11 -D_FORTIFY_SOURCE=2 -Wall -fPIC -fPIE -pie" if test "x$enable_werror" = "xyes"; then CFLAGS="$CFLAGS -Werror" fi +if test "x$enable_debug" = "xyes"; then + CFLAGS="$CFLAGS -g" +fi + AC_ARG_ENABLE([thread-safety], [AS_HELP_STRING([--enable-thread-safety], [enforce thread-safety otherwise fail the build [default=yes]])], [enable_thread_safety=$enableval], [enable_thread_safety=yes]) diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index c288c51..0e1ba8d 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -276,6 +276,10 @@ liblxc_la_CFLAGS += -fsanitize=address \ -fno-omit-frame-pointer endif +if HAVE_ISULAD +liblxc_la_CFLAGS += -D_FORTIFY_SOURCE=2 -Wall +endif + if ENABLE_UBSAN liblxc_la_CFLAGS += -fsanitize=undefined endif @@ -286,7 +290,9 @@ liblxc_la_LDFLAGS = -pthread \ -version-info @LXC_ABI_MAJOR@ if HAVE_ISULAD -liblxc_la_LDFLAGS += @YAJL_LIBS@ +liblxc_la_LDFLAGS += @YAJL_LIBS@ -Wl,-z,relro \ + -Wl,-z,now \ + -Wl,-z,noexecstack endif liblxc_la_LIBADD = $(CAP_LIBS) \ diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index b6aef12..1047c08 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -214,6 +214,7 @@ static char *read_file(const char *fnam) return move_ptr(buf); } +#ifndef HAVE_ISULAD /* Taken over modified from the kernel sources. */ #define NBITS 32 /* bits in uint32_t */ #define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) @@ -476,12 +477,14 @@ static bool copy_parent_file(const char *parent_cgroup, value, child_cgroup, file); return true; } +#endif static inline bool is_unified_hierarchy(const struct hierarchy *h) { return h->version == CGROUP2_SUPER_MAGIC; } +#ifndef HAVE_ISULAD /* * Initialize the cpuset hierarchy in first directory of @cgroup_leaf and set * cgroup.clone_children so that children inherit settings. Since the @@ -561,6 +564,7 @@ static int cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, return fret; } +#endif /* Given two null-terminated lists of strings, return true if any string is in * both. @@ -946,29 +950,6 @@ static void lxc_cgfsng_print_basecg_debuginfo(char *basecginfo, char **klist, TRACE("named subsystem %d: %s", k, *it); } -static int cgroup_tree_remove(struct hierarchy **hierarchies, - const char *container_cgroup) -{ - if (!container_cgroup || !hierarchies) - return 0; - - for (int i = 0; hierarchies[i]; i++) { - struct hierarchy *h = hierarchies[i]; - int ret; - - if (!h->container_full_path) - continue; - - ret = lxc_rm_rf(h->container_full_path); - if (ret < 0) - WARN("Failed to destroy \"%s\"", h->container_full_path); - - free_disarm(h->container_full_path); - } - - return 0; -} - struct generic_userns_exec_data { struct hierarchy **hierarchies; const char *container_cgroup; @@ -977,29 +958,6 @@ struct generic_userns_exec_data { char *path; }; -static int cgroup_tree_remove_wrapper(void *data) -{ - struct generic_userns_exec_data *arg = data; - uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid; - gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid; - int ret; - - if (!lxc_setgroups(0, NULL) && errno != EPERM) - return log_error_errno(-1, errno, "Failed to setgroups(0, NULL)"); - - ret = setresgid(nsgid, nsgid, nsgid); - if (ret < 0) - return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)", - (int)nsgid, (int)nsgid, (int)nsgid); - - ret = setresuid(nsuid, nsuid, nsuid); - if (ret < 0) - return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)", - (int)nsuid, (int)nsuid, (int)nsuid); - - return cgroup_tree_remove(arg->hierarchies, arg->container_cgroup); -} - #ifdef HAVE_ISULAD static int isulad_cgroup_tree_remove(struct hierarchy **hierarchies, @@ -1100,6 +1058,52 @@ __cgfsng_ops static bool isulad_cgfsng_payload_destroy(struct cgroup_ops *ops, return true; } #else +static int cgroup_tree_remove(struct hierarchy **hierarchies, + const char *container_cgroup) +{ + if (!container_cgroup || !hierarchies) + return 0; + + for (int i = 0; hierarchies[i]; i++) { + struct hierarchy *h = hierarchies[i]; + int ret; + + if (!h->container_full_path) + continue; + + ret = lxc_rm_rf(h->container_full_path); + if (ret < 0) + WARN("Failed to destroy \"%s\"", h->container_full_path); + + free_disarm(h->container_full_path); + } + + return 0; +} + +static int cgroup_tree_remove_wrapper(void *data) +{ + struct generic_userns_exec_data *arg = data; + uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid; + gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid; + int ret; + + if (!lxc_setgroups(0, NULL) && errno != EPERM) + return log_error_errno(-1, errno, "Failed to setgroups(0, NULL)"); + + ret = setresgid(nsgid, nsgid, nsgid); + if (ret < 0) + return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)", + (int)nsgid, (int)nsgid, (int)nsgid); + + ret = setresuid(nsuid, nsuid, nsuid); + if (ret < 0) + return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)", + (int)nsuid, (int)nsuid, (int)nsuid); + + return cgroup_tree_remove(arg->hierarchies, arg->container_cgroup); +} + __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, struct lxc_handler *handler) { @@ -1227,6 +1231,14 @@ try_lxc_rm_rf: } #endif +#ifdef HAVE_ISULAD +__cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, + struct lxc_handler *handler) +{ + return true; +} +#else + static int mkdir_eexist_on_last(const char *dir, mode_t mode) { const char *tmp = dir; @@ -1311,13 +1323,6 @@ static void cgroup_tree_leaf_remove(struct hierarchy *h, bool payload) SYSWARN("Failed to rmdir(\"%s\") cgroup", full_path); } -#ifdef HAVE_ISULAD -__cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, - struct lxc_handler *handler) -{ - return true; -} -#else __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, struct lxc_handler *handler) { @@ -3038,6 +3043,7 @@ static int device_cgroup_parse_access(struct device_item *device, const char *va return 0; } +#ifndef HAVE_ISULAD static int device_cgroup_rule_parse(struct device_item *device, const char *key, const char *val) { @@ -3124,6 +3130,7 @@ static int device_cgroup_rule_parse(struct device_item *device, const char *key, return device_cgroup_parse_access(device, ++val); } +#endif #ifdef HAVE_ISULAD __cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops, @@ -3307,6 +3314,7 @@ static int convert_devpath(const char *invalue, char *dest) return 0; } +#ifndef HAVE_ISULAD /* Called from setup_limits - here we have the container's cgroup_data because * we created the cgroups. */ @@ -3339,6 +3347,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, return lxc_write_openat(h->container_full_path, filename, value, strlen(value)); } +#endif #ifdef HAVE_ISULAD /* Called from setup_limits - here we have the container's cgroup_data because @@ -3923,7 +3932,6 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg __do_free char *base_cgroup = NULL, *mountpoint = NULL; __do_free_string_list char **controller_list = NULL; int type; - bool writeable; struct hierarchy *new; type = get_cgroup_version(line); @@ -3989,6 +3997,7 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg base_cgroup[1] = '\0'; } #else + bool writeable; if (type == CGROUP2_SUPER_MAGIC) writeable = test_writeable_v2(mountpoint, base_cgroup); else diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 55cba6d..f00afe9 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -6228,7 +6228,6 @@ static int get_config_init_args(const char *key, char *retv, int inlen, struct lxc_conf *c, void *data) { int i, len, fulllen = 0; - struct lxc_list *it; if (!retv) inlen = 0; diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c index 14686fc..c0a4d1a 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c @@ -287,6 +287,7 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) return lxc_terminal_create_log_file(terminal); } +#ifndef HAVE_ISULAD static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, int bytes_read) { @@ -392,6 +393,7 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, bytes_read -= ret; return bytes_read; } +#endif #ifdef HAVE_ISULAD /* get time buffer */ @@ -1240,8 +1242,8 @@ void lxc_terminal_free(struct lxc_conf *conf, int fd) static int lxc_terminal_peer_default(struct lxc_terminal *terminal) { - struct lxc_terminal_state *ts; - const char *path; + struct lxc_terminal_state *ts = NULL; + const char *path = NULL; int ret = 0; if (terminal->path) diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c index b068c9a..48e18bb 100644 --- a/src/lxc/tools/lxc_attach.c +++ b/src/lxc/tools/lxc_attach.c @@ -507,11 +507,9 @@ out: int main(int argc, char *argv[]) { - int ret = -1; int wexit = 0; struct lxc_log log; char *errmsg = NULL; - pid_t pid; lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; lxc_attach_command_t command = (lxc_attach_command_t){.program = NULL}; diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 39413ee..ba69995 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -1427,9 +1427,11 @@ static int lxc_get_unused_loop_dev(char *name_loop) { int loop_nr, ret; int fd_ctl = -1, fd_tmp = -1; +#if HAVE_ISULAD // isulad: retry and try mknod int max_retry = 200; bool try_mknod = true; +#endif fd_ctl = open("/dev/loop-control", O_RDWR | O_CLOEXEC); if (fd_ctl < 0) { @@ -1446,7 +1448,10 @@ static int lxc_get_unused_loop_dev(char *name_loop) ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr); if (ret < 0 || ret >= LO_NAME_SIZE) goto on_error; + +#if HAVE_ISULAD retry: +#endif fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC); if (fd_tmp < 0) { #if HAVE_ISULAD @@ -1693,6 +1698,7 @@ uint64_t lxc_find_next_power2(uint64_t n) return n; } +#ifndef HAVE_ISULAD static int process_dead(/* takes */ int status_fd) { __do_close int dupfd = -EBADF; @@ -1730,6 +1736,7 @@ static int process_dead(/* takes */ int status_fd) return ret; } +#endif int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd) { -- 1.8.3.1