From e0f6f149d513a52081955980f4091b36ded85029 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 18 Jan 2022 16:14:13 +0100 Subject: [PATCH 01/13] conf: improve userns_exec_mapped_root() As we do in all other places, first drop groups, then use setres{g,u}id(). Signed-off-by: Christian Brauner --- src/lxc/conf.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index fe54718a9..62ea6ae54 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -5505,11 +5505,20 @@ int userns_exec_mapped_root(const char *path, int path_fd, close_prot_errno_disarm(sock_fds[0]); - if (!lxc_switch_uid_gid(0, 0)) + if (!lxc_drop_groups() && errno != EPERM) _exit(EXIT_FAILURE); - if (!lxc_drop_groups()) + ret = setresgid(0, 0, 0); + if (ret < 0) { + SYSERROR("Failed to setresgid(0, 0, 0)"); _exit(EXIT_FAILURE); + } + + ret = setresuid(0, 0, 0); + if (ret < 0) { + SYSERROR("Failed to setresuid(0, 0, 0)"); + _exit(EXIT_FAILURE); + } ret = fchown(target_fd, 0, st.st_gid); if (ret) { From e5af72a666e3027a032c4ac4ea3df3880a51b907 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 18 Jan 2022 16:26:58 +0100 Subject: [PATCH 02/13] conf: log termination status Signed-off-by: Christian Brauner --- src/lxc/conf.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 62ea6ae54..74bf5178d 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -5566,9 +5566,19 @@ on_error: /* Wait for child to finish. */ if (pid < 0) - return -1; + return log_error(-1, "Failed to create child process"); - return wait_for_pid(pid); + ret = lxc_wait_for_pid_status(pid); + if (ret < 0) + return syserror("Failed to wait on child process %d", pid); + if (WIFSIGNALED(ret)) + return log_error(-1, "Child process %d terminated by signal %ld", pid, WTERMSIG(ret)); + if (!WIFEXITED(ret)) + return log_error(-1, "Child did not termiate correctly"); + if (WEXITSTATUS(ret)) + return log_error(-1, "Child terminated with error %ld", WEXITSTATUS(ret)); + + return 0; } /* not thread-safe, do not use from api without first forking */ From 78ffe0110885f5196bc9647917b56189237e0b50 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 18 Jan 2022 16:57:47 +0100 Subject: [PATCH 03/13] lxccontainer: improve do_lxcapi_save_config() Signed-off-by: Christian Brauner --- src/lxc/lxccontainer.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 96fdb3fd2..cc8be8938 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2605,28 +2605,26 @@ WRAP_API_3(int, lxcapi_get_keys, const char *, char *, int) static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file) { - int fd, lret; - bool ret = false, need_disklock = false; + __do_close int fd_config = -EBADF; + int lret = -1; + bool bret = false, need_disklock = false; if (!alt_file) alt_file = c->configfile; if (!alt_file) - return false; + return log_error(false, "No config file found"); /* If we haven't yet loaded a config, load the stock config. */ if (!c->lxc_conf) { if (!do_lxcapi_load_config(c, lxc_global_config_value("lxc.default_config"))) { - ERROR("Error loading default configuration file %s " - "while saving %s", - lxc_global_config_value("lxc.default_config"), - c->name); - return false; + return log_error(false, "Error loading default configuration file %s while saving %s", + lxc_global_config_value("lxc.default_config"), c->name); } } if (!create_container_dir(c)) - return false; + return log_error(false, "Failed to create container directory"); /* If we're writing to the container's config file, take the disk lock. * Otherwise just take the memlock to protect the struct lxc_container @@ -2640,19 +2638,23 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file) else lret = container_mem_lock(c); if (lret) - return false; + return log_error(false, "Failed to acquire lock"); - fd = open(alt_file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (fd < 0) + fd_config = open(alt_file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (fd_config < 0) { + SYSERROR("Failed to open config file \"%s\"", alt_file); goto on_error; + } - lret = write_config(fd, c->lxc_conf); - close(fd); - if (lret < 0) + lret = write_config(fd_config, c->lxc_conf); + if (lret < 0) { + SYSERROR("Failed to write config file \"%s\"", alt_file); goto on_error; + } - ret = true; + bret = true; + TRACE("Saved config file \"%s\"", alt_file); on_error: if (need_disklock) @@ -2660,7 +2662,7 @@ on_error: else container_mem_unlock(c); - return ret; + return bret; } WRAP_API_1(bool, lxcapi_save_config, const char *) From 07ea844f4e645d2f2a3a8a17b23400f2acbd6867 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 18 Jan 2022 17:25:07 +0100 Subject: [PATCH 04/13] lxccontainer: improve do_lxcapi_create() Signed-off-by: Christian Brauner --- src/lxc/conf.c | 11 ++--------- src/lxc/lxccontainer.c | 34 ++++++++++++++++++++-------------- src/lxc/utils.c | 18 ++++++++++++++++++ src/lxc/utils.h | 1 + 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 74bf5178d..e656f63bb 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -5568,15 +5568,8 @@ on_error: if (pid < 0) return log_error(-1, "Failed to create child process"); - ret = lxc_wait_for_pid_status(pid); - if (ret < 0) - return syserror("Failed to wait on child process %d", pid); - if (WIFSIGNALED(ret)) - return log_error(-1, "Child process %d terminated by signal %ld", pid, WTERMSIG(ret)); - if (!WIFEXITED(ret)) - return log_error(-1, "Child did not termiate correctly"); - if (WEXITSTATUS(ret)) - return log_error(-1, "Child terminated with error %ld", WEXITSTATUS(ret)); + if (!wait_exited(pid)) + return -1; return 0; } diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index cc8be8938..dab6daa94 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1777,7 +1777,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, int partial_fd; mode_t mask; pid_t pid; - bool ret = false, rootfs_managed = true; + bool bret = false, rootfs_managed = true; if (!c) return false; @@ -1785,7 +1785,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, if (t) { path_template = get_template_path(t); if (!path_template) - return syserror_set(ENOENT, "Template \"%s\" not found", t); + return log_error(false, "Template \"%s\" not found", t); } /* If a template is passed in, and the rootfs already is defined in the @@ -1794,15 +1794,16 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, */ if (do_lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) == 0 && path_template) - return syserror_set(EEXIST, "Container \"%s\" already exists in \"%s\"", c->name, c->config_path); + return log_error(false, "Container \"%s\" already exists in \"%s\"", + c->name, c->config_path); if (!c->lxc_conf && !do_lxcapi_load_config(c, lxc_global_config_value("lxc.default_config"))) - return syserror_set(EINVAL, "Failed to load default configuration file %s", - lxc_global_config_value("lxc.default_config")); + return log_error(false, "Failed to load default configuration file %s", + lxc_global_config_value("lxc.default_config")); if (!create_container_dir(c)) - return syserror_set(EINVAL, "Failed to create container %s", c->name); + return log_error(false, "Failed to create container %s", c->name); if (c->lxc_conf->rootfs.path) rootfs_managed = false; @@ -1817,13 +1818,16 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, ERROR("Failed to save initial config for \"%s\"", c->name); goto out; } - ret = true; + + bret = true; goto out; } /* Rootfs passed into configuration, but does not exist. */ - if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) != 0) + if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) != 0) { + ERROR("The rootfs \"%s\" does not exist", c->lxc_conf->rootfs.path); goto out; + } if (do_lxcapi_is_defined(c) && c->lxc_conf->rootfs.path && !path_template) { /* Rootfs already existed, user just wanted to save the loaded @@ -1832,14 +1836,16 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, if (!c->save_config(c, NULL)) ERROR("Failed to save initial config for \"%s\"", c->name); - ret = true; + bret = true; goto out; } /* Mark that this container is being created */ partial_fd = create_partial(c); - if (partial_fd < 0) + if (partial_fd < 0) { + SYSERROR("Failed to mark container as being partially created"); goto out; + } /* No need to get disk lock bc we have the partial lock. */ @@ -1881,7 +1887,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, _exit(EXIT_SUCCESS); } - if (wait_for_pid(pid) != 0) + if (!wait_exited(pid)) goto out_unlock; /* Reload config to get the rootfs. */ @@ -1906,14 +1912,14 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, } } - ret = load_config_locked(c, c->configfile); + bret = load_config_locked(c, c->configfile); out_unlock: umask(mask); remove_partial(c, partial_fd); out: - if (!ret) { + if (!bret) { bool reset_managed = c->lxc_conf->rootfs.managed; /* @@ -1926,7 +1932,7 @@ out: c->lxc_conf->rootfs.managed = reset_managed; } - return ret; + return bret; } static bool lxcapi_create(struct lxc_container *c, const char *t, diff --git a/src/lxc/utils.c b/src/lxc/utils.c index bc8a2b0c3..b2cfb865d 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -329,6 +329,24 @@ again: return status; } +bool wait_exited(pid_t pid) +{ + int status; + + status = lxc_wait_for_pid_status(pid); + if (status < 0) + return log_error(false, "Failed to reap on child process %d", pid); + if (WIFSIGNALED(status)) + return log_error(false, "Child process %d terminated by signal %d", pid, WTERMSIG(status)); + if (!WIFEXITED(status)) + return log_error(false, "Child did not termiate correctly"); + if (WEXITSTATUS(status)) + return log_error(false, "Child terminated with error %d", WEXITSTATUS(status)); + + TRACE("Reaped child process %d", pid); + return true; +} + #ifdef HAVE_OPENSSL #include diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 7b1017265..87feeed76 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -81,6 +81,7 @@ static inline void __auto_lxc_pclose__(struct lxc_popen_FILE **f) __hidden extern int wait_for_pid(pid_t pid); __hidden extern int lxc_wait_for_pid_status(pid_t pid); __hidden extern int wait_for_pidfd(int pidfd); +__hidden extern bool wait_exited(pid_t pid); #if HAVE_OPENSSL __hidden extern int sha1sum_file(char *fnam, unsigned char *md_value, unsigned int *md_len); From 0e375b104bc041687050c4ce110c24cbff116b08 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 18 Jan 2022 17:48:29 +0100 Subject: [PATCH 05/13] lxccontainer: improve create_partial() Signed-off-by: Christian Brauner --- src/lxc/lxccontainer.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index dab6daa94..1a5567aa9 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -173,38 +173,41 @@ static int ongoing_create(struct lxc_container *c) static int create_partial(struct lxc_container *c) { __do_free char *path = NULL; - int fd, ret; + __do_close int fd_partial = -EBADF; + int ret; size_t len; struct flock lk = {0}; /* $lxcpath + '/' + $name + '/partial' + \0 */ len = strlen(c->config_path) + 1 + strlen(c->name) + 1 + strlen(LXC_PARTIAL_FNAME) + 1; - path = must_realloc(NULL, len); + path = malloc(len); + if (!path) + return ret_errno(ENOMEM); + ret = strnprintf(path, len, "%s/%s/%s", c->config_path, c->name, LXC_PARTIAL_FNAME); if (ret < 0) - return -1; + return -errno; - fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0000); - if (fd < 0) - return -1; + fd_partial = open(path, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0000); + if (fd_partial < 0) + return syserror("Failed to create \"%s\" to mark container as partially created", path); lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; - ret = fcntl(fd, F_OFD_SETLKW, &lk); + ret = fcntl(fd_partial, F_OFD_SETLKW, &lk); if (ret < 0) { if (errno == EINVAL) { - ret = flock(fd, LOCK_EX); + ret = flock(fd_partial, LOCK_EX); if (ret == 0) - return fd; + return move_fd(fd_partial); } - SYSERROR("Failed to lock partial file %s", path); - close(fd); - return -1; + return syserror("Failed to lock partial file %s", path); } - return fd; + TRACE("Created \"%s\" to mark container as partially created", path); + return move_fd(fd_partial); } static void remove_partial(struct lxc_container *c, int fd) @@ -1840,7 +1843,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, goto out; } - /* Mark that this container is being created */ + /* Mark that this container as being created */ partial_fd = create_partial(c); if (partial_fd < 0) { SYSERROR("Failed to mark container as being partially created"); From c123aa042a66db918de18be0133e8483ee5d2256 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 18 Jan 2022 18:44:37 +0100 Subject: [PATCH 06/13] lxccontainer: simplify partial file creation Signed-off-by: Christian Brauner --- src/lxc/lxccontainer.c | 77 +++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 1a5567aa9..0011e5292 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -170,27 +170,15 @@ static int ongoing_create(struct lxc_container *c) return LXC_CREATE_INCOMPLETE; } -static int create_partial(struct lxc_container *c) +static int create_partial(int fd_rootfs, struct lxc_container *c) { - __do_free char *path = NULL; __do_close int fd_partial = -EBADF; int ret; - size_t len; struct flock lk = {0}; - /* $lxcpath + '/' + $name + '/partial' + \0 */ - len = strlen(c->config_path) + 1 + strlen(c->name) + 1 + strlen(LXC_PARTIAL_FNAME) + 1; - path = malloc(len); - if (!path) - return ret_errno(ENOMEM); - - ret = strnprintf(path, len, "%s/%s/%s", c->config_path, c->name, LXC_PARTIAL_FNAME); - if (ret < 0) - return -errno; - - fd_partial = open(path, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0000); + fd_partial = openat(fd_rootfs, LXC_PARTIAL_FNAME, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0000); if (fd_partial < 0) - return syserror("Failed to create \"%s\" to mark container as partially created", path); + return syserror("errno(%d) - Failed to create \"%d/" LXC_PARTIAL_FNAME "\" to mark container as partially created", errno, fd_rootfs); lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; @@ -203,10 +191,10 @@ static int create_partial(struct lxc_container *c) return move_fd(fd_partial); } - return syserror("Failed to lock partial file %s", path); + return syserror("Failed to lock partial file \"%d/" LXC_PARTIAL_FNAME"\"", fd_rootfs); } - TRACE("Created \"%s\" to mark container as partially created", path); + TRACE("Created \"%d/" LXC_PARTIAL_FNAME "\" to mark container as partially created", fd_rootfs); return move_fd(fd_partial); } @@ -1206,32 +1194,31 @@ WRAP_API(bool, lxcapi_stop) static int do_create_container_dir(const char *path, struct lxc_conf *conf) { - int lasterr; + __do_close int fd_rootfs = -EBADF; int ret = -1; mode_t mask = umask(0002); ret = mkdir(path, 0770); - lasterr = errno; umask(mask); - errno = lasterr; - if (ret) { - if (errno != EEXIST) - return -1; + if (ret < 0 && errno != EEXIST) + return -errno; - ret = 0; - } + fd_rootfs = open_at(-EBADF, path, O_DIRECTORY | O_CLOEXEC, PROTECT_LOOKUP_ABSOLUTE_WITH_SYMLINKS, 0); + if (fd_rootfs < 0) + return syserror("Failed to open container directory \"%d(%s)\"", fd_rootfs, path); - if (!list_empty(&conf->id_map)) { - ret = chown_mapped_root(path, conf); - if (ret < 0) - ret = -1; - } + if (list_empty(&conf->id_map)) + return move_fd(fd_rootfs); - return ret; + ret = userns_exec_mapped_root(NULL, fd_rootfs, conf); + if (ret < 0) + return syserror_ret(-1, "Failed to chown rootfs \"%s\"", path); + + return move_fd(fd_rootfs); } /* Create the standard expected container dir. */ -static bool create_container_dir(struct lxc_container *c) +static int create_container_dir(struct lxc_container *c) { __do_free char *s = NULL; int ret; @@ -1240,13 +1227,13 @@ static bool create_container_dir(struct lxc_container *c) len = strlen(c->config_path) + strlen(c->name) + 2; s = malloc(len); if (!s) - return false; + return ret_errno(ENOMEM); ret = strnprintf(s, len, "%s/%s", c->config_path, c->name); if (ret < 0) - return false; + return -errno; - return do_create_container_dir(s, c->lxc_conf) == 0; + return do_create_container_dir(s, c->lxc_conf); } /* do_storage_create: thin wrapper around storage_create(). Like @@ -1776,6 +1763,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, const char *bdevtype, struct bdev_specs *specs, int flags, char *const argv[]) { + __do_close int fd_rootfs = -EBADF; __do_free char *path_template = NULL; int partial_fd; mode_t mask; @@ -1805,7 +1793,8 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, return log_error(false, "Failed to load default configuration file %s", lxc_global_config_value("lxc.default_config")); - if (!create_container_dir(c)) + fd_rootfs = create_container_dir(c); + if (fd_rootfs < 0) return log_error(false, "Failed to create container %s", c->name); if (c->lxc_conf->rootfs.path) @@ -1844,7 +1833,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, } /* Mark that this container as being created */ - partial_fd = create_partial(c); + partial_fd = create_partial(fd_rootfs, c); if (partial_fd < 0) { SYSERROR("Failed to mark container as being partially created"); goto out; @@ -2614,7 +2603,7 @@ WRAP_API_3(int, lxcapi_get_keys, const char *, char *, int) static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file) { - __do_close int fd_config = -EBADF; + __do_close int fd_config = -EBADF, fd_rootfs = -EBADF; int lret = -1; bool bret = false, need_disklock = false; @@ -2632,7 +2621,8 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file) } } - if (!create_container_dir(c)) + fd_rootfs = create_container_dir(c); + if (fd_rootfs < 0) return log_error(false, "Failed to create container directory"); /* If we're writing to the container's config file, take the disk lock. @@ -3753,17 +3743,18 @@ only rootfs gets converted (copied/snapshotted) on clone. static int create_file_dirname(char *path, struct lxc_conf *conf) { - char *p = strrchr(path, '/'); - int ret = -1; + __do_close int fd_rootfs = -EBADF; + char *p; + p = strrchr(path, '/'); if (!p) return -1; *p = '\0'; - ret = do_create_container_dir(path, conf); + fd_rootfs = do_create_container_dir(path, conf); *p = '/'; - return ret; + return fd_rootfs >= 0; } static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char *newname, From f7d3ef83800eeb20e9332ef468319a803857ea13 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 20 Jan 2022 09:42:28 +0100 Subject: [PATCH 07/13] build: only enable LTO for regular builds Signed-off-by: Christian Brauner --- configure.ac | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0ae5ad6fc..e7f9d54f0 100644 --- a/configure.ac +++ b/configure.ac @@ -500,7 +500,9 @@ if test "x$enable_fuzzers" = "xyes"; then CC_CHECK_FLAGS_APPEND([AM_CFLAGS],[CFLAGS],[ \ -DRUN_ON_OSS_FUZZ=1]) fi -else +fi + +if test "x$enable_fuzzers" = "xno" -a "x$enable_sanitizers" = "xno"; then CC_CHECK_FLAGS_APPEND([AM_CFLAGS],[CFLAGS],[-flto=thin]) fi AC_SUBST(AM_CFLAGS) From e27637b7b93bb0f00f105ff3b29e5d8d5bd5816e Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 20 Jan 2022 09:57:21 +0100 Subject: [PATCH 08/13] build: simplify thread local storage handling Signed-off-by: Christian Brauner --- config/tls.m4 | 14 -------------- configure.ac | 3 --- src/lxc/compiler.h | 8 +++++++- 3 files changed, 7 insertions(+), 18 deletions(-) delete mode 100644 config/tls.m4 diff --git a/config/tls.m4 b/config/tls.m4 deleted file mode 100644 index cd032c9d7..000000000 --- a/config/tls.m4 +++ /dev/null @@ -1,14 +0,0 @@ -# See if we have working TLS. We only check to see if it compiles, and that -# the resulting program actually runs, not whether the resulting TLS variables -# work properly; that check is done at runtime, since we can run binaries -# compiled with __thread on systems without TLS. -AC_DEFUN([LXC_CHECK_TLS], -[ - AC_MSG_CHECKING(for TLS) - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ static __thread int val; int main() { return 0; } ]])],[have_tls=yes],[have_tls=no],[have_tls=no ]) - AC_MSG_RESULT($have_tls) - if test "$have_tls" = "yes"; then - AC_DEFINE([HAVE_TLS],[1],[Define if the compiler supports __thread]) - AC_DEFINE([thread_local],[__thread],[Define to the compiler TLS keyword]) - fi -]) diff --git a/configure.ac b/configure.ac index e7f9d54f0..581f0d7d4 100644 --- a/configure.ac +++ b/configure.ac @@ -777,9 +777,6 @@ AC_CHECK_TYPES([struct rtnl_link_stats64], [], [], [[#include ] AX_PTHREAD AC_SEARCH_LIBS(clock_gettime, [rt]) -# See if we support thread-local storage. -LXC_CHECK_TLS - # Hardening flags CC_CHECK_FLAGS_APPEND([AM_CFLAGS],[CFLAGS],[ \ -fPIE \ diff --git a/src/lxc/compiler.h b/src/lxc/compiler.h index 4d6232382..907941d98 100644 --- a/src/lxc/compiler.h +++ b/src/lxc/compiler.h @@ -5,8 +5,14 @@ #include "config.h" -#include +#include +#include +#include #include +#include +#include +#include +#include #ifndef thread_local #if __STDC_VERSION__ >= 201112L && \ From e53abc41963117b1eb5cd1fe166c12d3a04d5c04 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 20 Jan 2022 10:14:13 +0100 Subject: [PATCH 09/13] lxccontainer: properly wrap lxcapi_create() Signed-off-by: Christian Brauner --- src/lxc/lxccontainer.c | 46 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 0011e5292..5dbfc0fc5 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -443,7 +443,26 @@ static rettype fnname(struct lxc_container *c, t1 a1, t2 a2, t3 a3) \ return ret; \ } -#define WRAP_API_6(rettype, fnname, t1, t2, t3, t4, t5, t6) \ +#define WRAP_API_5(rettype, fnname, t1, t2, t3, t4, t5) \ +static rettype fnname(struct lxc_container *c, t1 a1, t2 a2, t3 a3, \ + t4 a4, t5 a5) \ +{ \ + rettype ret; \ + bool reset_config = false; \ + \ + if (!current_config && c && c->lxc_conf) { \ + current_config = c->lxc_conf; \ + reset_config = true; \ + } \ + \ + ret = do_##fnname(c, a1, a2, a3, a4, a5); \ + if (reset_config) \ + current_config = NULL; \ + \ + return ret; \ +} + +#define WRAP_API_6(rettype, fnname, t1, t2, t3, t4, t5, t6) \ static rettype fnname(struct lxc_container *c, t1 a1, t2 a2, t3 a3, \ t4 a4, t5 a5, t6 a6) \ { \ @@ -1759,9 +1778,9 @@ static void lxcapi_clear_config(struct lxc_container *c) * @argv: the arguments to pass to the template, terminated by NULL. If no * arguments, you can just pass NULL. */ -static bool do_lxcapi_create(struct lxc_container *c, const char *t, - const char *bdevtype, struct bdev_specs *specs, - int flags, char *const argv[]) +static bool __lxcapi_create(struct lxc_container *c, const char *t, + const char *bdevtype, struct bdev_specs *specs, + int flags, char *const argv[]) { __do_close int fd_rootfs = -EBADF; __do_free char *path_template = NULL; @@ -1927,19 +1946,16 @@ out: return bret; } -static bool lxcapi_create(struct lxc_container *c, const char *t, - const char *bdevtype, struct bdev_specs *specs, - int flags, char *const argv[]) +static bool do_lxcapi_create(struct lxc_container *c, const char *t, + const char *bdevtype, struct bdev_specs *specs, + int flags, char *const argv[]) { - bool ret; - - current_config = c ? c->lxc_conf : NULL; - - ret = do_lxcapi_create(c, t, bdevtype, specs, flags, argv); - current_config = NULL; - return ret; + return __lxcapi_create(c, t, bdevtype, specs, flags, argv); } +WRAP_API_5(bool, lxcapi_create, const char *, const char *, + struct bdev_specs *, int, char *const *) + static bool do_lxcapi_reboot(struct lxc_container *c) { __do_close int pidfd = -EBADF; @@ -2167,7 +2183,7 @@ static bool lxcapi_createl(struct lxc_container *c, const char *t, goto out; } - bret = do_lxcapi_create(c, t, bdevtype, specs, flags, args); + bret = __lxcapi_create(c, t, bdevtype, specs, flags, args); out: free(args); From 0fd92707a5ffbb28f4eec5629702959ef9c1da9c Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 20 Jan 2022 10:34:02 +0100 Subject: [PATCH 10/13] github: ensure system liblxc is wiped Signed-off-by: Christian Brauner --- .github/workflows/sanitizers.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sanitizers.sh b/.github/workflows/sanitizers.sh index 680ac796a..a10e24162 100755 --- a/.github/workflows/sanitizers.sh +++ b/.github/workflows/sanitizers.sh @@ -19,6 +19,7 @@ apt-get install --yes --no-install-recommends \ llvm lsb-release make openssl pkg-config python3-all-dev \ python3-setuptools rsync squashfs-tools uidmap unzip uuid-runtime \ wget xz-utils +apt-get remove --yes lxc-utils liblxc-common liblxc1 liblxc-dev ARGS="--enable-sanitizers --enable-tests --prefix=/usr/ --sysconfdir=/etc/ --localstatedir=/var/ --disable-no-undefined" case "$CC" in clang*) From 617efa73e1e125c485bf0568e39f9540853dd85f Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 20 Jan 2022 12:23:35 +0100 Subject: [PATCH 11/13] github: log system info Signed-off-by: Christian Brauner --- .github/workflows/build.yml | 8 ++++++++ .github/workflows/coverity.yml | 14 ++++++++++++++ .github/workflows/sanitizers.yml | 14 ++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7318151f..291fa5822 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,6 +30,14 @@ jobs: run: | ${CC} --version + - name: Kernel version + run: | + uname -a + + - name: Mount table + run: | + findmnt + - name: Build env: CC: ${{ matrix.compiler }} diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 7003729ed..9ea82a350 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -24,6 +24,20 @@ jobs: sudo apt-get install -qq gcc clang sudo apt-get install -qq libapparmor-dev libcap-dev libseccomp-dev libselinux1-dev linux-libc-dev docbook2x + - name: Compiler version + env: + CC: ${{ matrix.compiler }} + run: | + ${CC} --version + + - name: Kernel version + run: | + uname -a + + - name: Mount table + run: | + findmnt + - name: Run coverity run: | # Configure diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml index 4c66a47c4..76339e19c 100644 --- a/.github/workflows/sanitizers.yml +++ b/.github/workflows/sanitizers.yml @@ -15,6 +15,20 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - name: Compiler version + env: + CC: ${{ matrix.compiler }} + run: | + ${CC} --version + + - name: Kernel version + run: | + uname -a + + - name: Mount table + run: | + findmnt + - name: Build run: | sudo CC=${{ matrix.compiler }} CXX=${{ matrix.compiler }}++ .github/workflows/sanitizers.sh From a434e4d4f329f22034f72b9f81088ef4a1d81527 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 20 Jan 2022 12:33:57 +0100 Subject: [PATCH 12/13] github: more detailed compilation instructions Signed-off-by: Christian Brauner --- .github/workflows/sanitizers.sh | 35 ++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sanitizers.sh b/.github/workflows/sanitizers.sh index a10e24162..a1c53c216 100755 --- a/.github/workflows/sanitizers.sh +++ b/.github/workflows/sanitizers.sh @@ -21,7 +21,40 @@ apt-get install --yes --no-install-recommends \ wget xz-utils apt-get remove --yes lxc-utils liblxc-common liblxc1 liblxc-dev -ARGS="--enable-sanitizers --enable-tests --prefix=/usr/ --sysconfdir=/etc/ --localstatedir=/var/ --disable-no-undefined" +ARGS="--enable-sanitizers \ + --prefix=/usr/ \ + --disable-no-undefined \ + --build=x86_64-linux-gnu \ + --includedir=\${prefix}/include \ + --mandir=\${prefix}/share/man \ + --infodir=\${prefix}/share/info \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --disable-silent-rules \ + --libdir=\${prefix}/lib/x86_64-linux-gnu \ + --libexecdir=\${prefix}/lib/x86_64-linux-gnu \ + --disable-maintainer-mode \ + --disable-dependency-tracking \ + --libdir=\${prefix}/lib/x86_64-linux-gnu \ + --libexecdir=\${prefix}/lib/x86_64-linux-gnu \ + --with-rootfs-path=\${prefix}/lib/x86_64-linux-gnu/lxc \ + --enable-doc \ + --disable-rpath \ + --with-distro=ubuntu \ + --enable-commands \ + --enable-pam \ + --enable-tests \ + --enable-memfd-rexec \ + --disable-static-binaries \ + --enable-static \ + --enable-silent-rules \ + --enable-apparmor \ + --enable-capabilities \ + --enable-seccomp \ + --enable-selinux \ + --disable-liburing \ + --enable-werror" + case "$CC" in clang*) ARGS="$ARGS --enable-fuzzers" esac From 8c1c30368a8b2af6bb61d0e39ba50674eaa52dae Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 20 Jan 2022 12:35:06 +0100 Subject: [PATCH 13/13] github: add systemd-coredump Signed-off-by: Christian Brauner --- .github/workflows/sanitizers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sanitizers.sh b/.github/workflows/sanitizers.sh index a1c53c216..ee650a6cf 100755 --- a/.github/workflows/sanitizers.sh +++ b/.github/workflows/sanitizers.sh @@ -18,7 +18,7 @@ apt-get install --yes --no-install-recommends \ libpam0g-dev libseccomp-dev libselinux1-dev libtool linux-libc-dev \ llvm lsb-release make openssl pkg-config python3-all-dev \ python3-setuptools rsync squashfs-tools uidmap unzip uuid-runtime \ - wget xz-utils + wget xz-utils systemd-coredump apt-get remove --yes lxc-utils liblxc-common liblxc1 liblxc-dev ARGS="--enable-sanitizers \