Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package lxc for openSUSE:Factory checked in at 2023-07-31 15:24:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/lxc (Old) and /work/SRC/openSUSE:Factory/.lxc.new.32662 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "lxc" Mon Jul 31 15:24:42 2023 rev:106 rq:1101506 version:5.0.3 Changes: -------- --- /work/SRC/openSUSE:Factory/lxc/lxc.changes 2023-05-15 16:54:59.304394288 +0200 +++ /work/SRC/openSUSE:Factory/.lxc.new.32662/lxc.changes 2023-07-31 15:24:50.179485960 +0200 @@ -1,0 +2,9 @@ +Mon Jul 31 10:43:32 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 5.0.3: + * Fix nftables syntax for IPv6 NAT + * Added support for squashfs OCI images + * Fixes when running LXC with io_uring + + detailed changelog at https://discuss.linuxcontainers.org/t/lxc-5-0-3-lts-has-been-released/17708 + +------------------------------------------------------------------- Old: ---- lxc-5.0.2.tar.gz lxc-5.0.2.tar.gz.asc New: ---- lxc-5.0.3.tar.gz lxc-5.0.3.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ lxc.spec ++++++ --- /var/tmp/diff_new_pack.M0PucJ/_old 2023-07-31 15:24:50.923490255 +0200 +++ /var/tmp/diff_new_pack.M0PucJ/_new 2023-07-31 15:24:50.927490278 +0200 @@ -23,7 +23,7 @@ %define shlib_version 1 Name: lxc -Version: 5.0.2 +Version: 5.0.3 Release: 0 URL: http://linuxcontainers.org/ Summary: Userspace tools for Linux kernel containers ++++++ lxc-5.0.2.tar.gz -> lxc-5.0.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/.github/workflows/commits.yml new/lxc-5.0.3/.github/workflows/commits.yml --- old/lxc-5.0.2/.github/workflows/commits.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/lxc-5.0.3/.github/workflows/commits.yml 2023-07-26 00:00:11.000000000 +0200 @@ -0,0 +1,40 @@ +name: Commits +on: + - pull_request + +permissions: + contents: read + +jobs: + dco-check: + permissions: + pull-requests: read # for tim-actions/get-pr-commits to get list of commits from the PR + name: Signed-off-by (DCO) + runs-on: ubuntu-22.04 + steps: + - name: Get PR Commits + id: 'get-pr-commits' + uses: tim-actions/get-pr-commits@master + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check that all commits are signed-off + uses: tim-actions/dco@master + with: + commits: ${{ steps.get-pr-commits.outputs.commits }} + + target-branch: + permissions: + contents: none + name: Branch target + runs-on: ubuntu-22.04 + steps: + - name: Check branch target + env: + TARGET: ${{ github.event.pull_request.base.ref }} + run: | + set -x + [ "${TARGET}" = "main" ] && exit 0 + + echo "Invalid branch target: ${TARGET}" + exit 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/CONTRIBUTING new/lxc-5.0.3/CONTRIBUTING --- old/lxc-5.0.2/CONTRIBUTING 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/CONTRIBUTING 2023-07-26 00:00:11.000000000 +0200 @@ -107,3 +107,15 @@ Co-developed-by: Random J Developer 1 <rando...@developer.org> Co-developed-by: Random J Developer 2 <rando...@developer.org> + +AI Generated Code: +------------------ + +Substantially AI generated code is not welcome. There are several +reasons for this. First, it violates the "The contribution was created +in whole or in part by me" statement of DCO. Second, the licensing +implications are not yet clear. Thirdly, we expect anyone who submits +code to fully understand what they are submitting. Finally, we put +a lot of time into reviewing patch submissions. Increasing the +volume of code to be reviewed with autogenerated boilerplate drivel +will take away time from more important reviews. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/config/apparmor/abstractions/start-container.in new/lxc-5.0.3/config/apparmor/abstractions/start-container.in --- old/lxc-5.0.2/config/apparmor/abstractions/start-container.in 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/config/apparmor/abstractions/start-container.in 2023-07-26 00:00:11.000000000 +0200 @@ -20,6 +20,7 @@ mount options=(rw, make-shared) -> **, mount options=(rw, make-rshared) -> **, mount fstype=debugfs, + mount fstype=fuse.*, # allow pre-mount hooks to stage mounts under /var/lib/lxc/<container>/ mount -> /var/lib/lxc/{**,}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/config/init/common/lxc-net.in new/lxc-5.0.3/config/init/common/lxc-net.in --- old/lxc-5.0.2/config/init/common/lxc-net.in 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/config/init/common/lxc-net.in 2023-07-26 00:00:11.000000000 +0200 @@ -92,7 +92,7 @@ add table ip6 lxc; flush table ip6 lxc; add chain ip6 lxc postrouting { type nat hook postrouting priority 100; }; -add rule ip6 lxc postrouting ip saddr ${LXC_IPV6_NETWORK} ip daddr != ${LXC_IPV6_NETWORK} counter masquerade; +add rule ip6 lxc postrouting ip6 saddr ${LXC_IPV6_NETWORK} ip6 daddr != ${LXC_IPV6_NETWORK} counter masquerade; " fi NFT_RULESET="${NFT_RULESET}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/meson.build new/lxc-5.0.3/meson.build --- old/lxc-5.0.2/meson.build 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/meson.build 2023-07-26 00:00:11.000000000 +0200 @@ -4,7 +4,7 @@ project( 'lxc', 'c', - version: '5.0.2', + version: '5.0.3', license: 'LGPLv2+', default_options: [ 'b_lto=true', @@ -30,7 +30,7 @@ version_data = configuration_data() version_data.set('LXC_VERSION_MAJOR', '5') version_data.set('LXC_VERSION_MINOR', '0') -version_data.set('LXC_VERSION_MICRO', '2') +version_data.set('LXC_VERSION_MICRO', '3') version_data.set('LXC_VERSION_BETA', '') version_data.set('LXC_ABI', liblxc_version) version_data.set('LXC_DEVEL', '0') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/attach.c new/lxc-5.0.3/src/lxc/attach.c --- old/lxc-5.0.2/src/lxc/attach.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/attach.c 2023-07-26 00:00:11.000000000 +0200 @@ -1319,7 +1319,7 @@ * here, ignore errors. */ for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) { - ret = fd_cloexec(fd, false); + ret = lxc_fd_cloexec(fd, false); if (ret < 0) { SYSERROR("Failed to clear FD_CLOEXEC from file descriptor %d", fd); goto on_error; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/cgroups/cgfsng.c new/lxc-5.0.3/src/lxc/cgroups/cgfsng.c --- old/lxc-5.0.2/src/lxc/cgroups/cgfsng.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/cgroups/cgfsng.c 2023-07-26 00:00:11.000000000 +0200 @@ -146,7 +146,7 @@ } if (controller) - WARN("There is no useable %s controller", controller); + INFO("There is no useable %s controller", controller); else WARN("There is no empty unified cgroup hierarchy"); @@ -2167,7 +2167,7 @@ hierarchy_mnt = must_make_path(cgroup_root, h->at_mnt, NULL); path2 = must_make_path(hierarchy_mnt, h->at_base, ops->container_cgroup, NULL); - ret = mkdir_p(path2, 0755); + ret = lxc_mkdir_p(path2, 0755); if (ret < 0 && (errno != EEXIST)) return false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/cgroups/cgroup_utils.c new/lxc-5.0.3/src/lxc/cgroups/cgroup_utils.c --- old/lxc-5.0.2/src/lxc/cgroups/cgroup_utils.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/cgroups/cgroup_utils.c 2023-07-26 00:00:11.000000000 +0200 @@ -26,7 +26,7 @@ struct statfs fs; ret = fstatfs(fd, &fs); - if (!ret && is_fs_type(&fs, CGROUP2_SUPER_MAGIC)) + if (!ret && lxc_is_fs_type(&fs, CGROUP2_SUPER_MAGIC)) return true; return false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/cmd/lxc_monitord.c new/lxc-5.0.3/src/lxc/cmd/lxc_monitord.c --- old/lxc-5.0.2/src/lxc/cmd/lxc_monitord.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/cmd/lxc_monitord.c 2023-07-26 00:00:11.000000000 +0200 @@ -159,17 +159,12 @@ socklen_t credsz = sizeof(cred); ret = LXC_MAINLOOP_ERROR; - clientfd = accept(fd, NULL, 0); + clientfd = accept4(fd, NULL, 0, SOCK_CLOEXEC); if (clientfd < 0) { SYSERROR("Failed to accept connection for client file descriptor %d", fd); goto out; } - if (fcntl(clientfd, F_SETFD, FD_CLOEXEC)) { - SYSERROR("Failed to set FD_CLOEXEC on client socket connection %d", clientfd); - goto err1; - } - if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED, &cred, &credsz)) { SYSERROR("Failed to get credentials on client socket connection %d", clientfd); goto err1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/commands.c new/lxc-5.0.3/src/lxc/commands.c --- old/lxc-5.0.2/src/lxc/commands.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/commands.c 2023-07-26 00:00:11.000000000 +0200 @@ -2080,14 +2080,10 @@ __do_close int connection = -EBADF; int opt = 1, ret = -1; - connection = accept(fd, NULL, 0); + connection = accept4(fd, NULL, 0, SOCK_CLOEXEC); if (connection < 0) return log_error_errno(LXC_MAINLOOP_ERROR, errno, "Failed to accept connection to run command"); - ret = fcntl(connection, F_SETFD, FD_CLOEXEC); - if (ret < 0) - return log_error_errno(ret, errno, "Failed to set close-on-exec on incoming command connection"); - ret = setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt)); if (ret < 0) return log_error_errno(ret, errno, "Failed to enable necessary credentials on command socket"); @@ -2122,10 +2118,6 @@ return log_error_errno(-1, errno, "Failed to create command socket %s", &path[1]); } - ret = fcntl(fd, F_SETFD, FD_CLOEXEC); - if (ret < 0) - return log_error_errno(-1, errno, "Failed to set FD_CLOEXEC on command socket file descriptor"); - return log_trace(move_fd(fd), "Created abstract unix socket \"%s\"", &path[1]); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/conf.c new/lxc-5.0.3/src/lxc/conf.c --- old/lxc-5.0.2/src/lxc/conf.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/conf.c 2023-07-26 00:00:11.000000000 +0200 @@ -2212,7 +2212,7 @@ static int parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size) { - ssize_t ret; + size_t ret; /* If '=' is contained in opt, the option must go into data. */ if (!strchr(opt, '=')) { @@ -2236,12 +2236,12 @@ if (strlen(*data)) { ret = strlcat(*data, ",", size); - if (ret < 0) + if (ret >= size) return log_error_errno(ret, errno, "Failed to append \",\" to %s", *data); } ret = strlcat(*data, opt, size); - if (ret < 0) + if (ret >= size) return log_error_errno(ret, errno, "Failed to append \"%s\" to %s", opt, *data); return 0; @@ -2597,7 +2597,7 @@ } if (hasmntopt(mntent, "create=dir")) { - ret = mkdir_p(path, 0755); + ret = lxc_mkdir_p(path, 0755); if (ret < 0 && errno != EEXIST) return log_error_errno(-1, errno, "Failed to create directory \"%s\"", path); } @@ -2615,7 +2615,7 @@ p2 = dirname(p1); - ret = mkdir_p(p2, 0755); + ret = lxc_mkdir_p(p2, 0755); if (ret < 0 && errno != EEXIST) return log_error_errno(-1, errno, "Failed to create directory \"%s\"", path); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/conf.h new/lxc-5.0.3/src/lxc/conf.h --- old/lxc-5.0.2/src/lxc/conf.h 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/conf.h 2023-07-26 00:00:11.000000000 +0200 @@ -233,7 +233,7 @@ * @path : the rootfs source (directory or device) * @mount : where it is mounted * @buf : static buffer to construct paths - * @bev_type : optional backing store type + * @bdev_type : optional backing store type * @managed : whether it is managed by LXC * @dfd_mnt : fd for @mount * @dfd_dev : fd for /dev of the container diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/confile.c new/lxc-5.0.3/src/lxc/confile.c --- old/lxc-5.0.2/src/lxc/confile.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/confile.c 2023-07-26 00:00:11.000000000 +0200 @@ -2770,7 +2770,7 @@ return 0; } - if (value[strlen(value)-1] == '/' || is_dir(value)) + if (value[strlen(value)-1] == '/' || lxc_is_dir(value)) return do_includedir(value, lxc_conf); return lxc_config_read(value, lxc_conf, true); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/confile_utils.c new/lxc-5.0.3/src/lxc/confile_utils.c --- old/lxc-5.0.2/src/lxc/confile_utils.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/confile_utils.c 2023-07-26 00:00:11.000000000 +0200 @@ -653,7 +653,7 @@ { __do_free char *valdup = NULL; - valdup = path_simplify(value); + valdup = lxc_path_simplify(value); if (!valdup) return -ENOMEM; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/criu.c new/lxc-5.0.3/src/lxc/criu.c --- old/lxc-5.0.2/src/lxc/criu.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/criu.c 2023-07-26 00:00:11.000000000 +0200 @@ -321,7 +321,7 @@ return log_error_errno(-ENOMEM, ENOMEM, "Failed to duplicate limit cgroup path"); } - tmp = path_simplify(cgroup_base_path); + tmp = lxc_path_simplify(cgroup_base_path); if (!tmp) return log_error_errno(-ENOMEM, ENOMEM, "Failed to remove extraneous slashes from \"%s\"", cgroup_base_path); free_move_ptr(cgroup_base_path, tmp); @@ -1224,7 +1224,7 @@ return false; } - if (mkdir_p(opts->directory, 0700) < 0) + if (lxc_mkdir_p(opts->directory, 0700) < 0) goto fail; pid = fork(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/file_utils.c new/lxc-5.0.3/src/lxc/file_utils.c --- old/lxc-5.0.2/src/lxc/file_utils.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/file_utils.c 2023-07-26 00:00:11.000000000 +0200 @@ -275,7 +275,7 @@ return ret; } -int is_dir(const char *path) +int lxc_is_dir(const char *path) { int ret; struct stat statbuf; @@ -332,7 +332,7 @@ return move_fd(fd); } -bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val) +bool lxc_is_fs_type(const struct statfs *fs, fs_type_magic magic_val) { return (fs->f_type == (fs_type_magic)magic_val); } @@ -346,7 +346,7 @@ if (ret < 0) return false; - return is_fs_type(&sb, magic_val); + return lxc_is_fs_type(&sb, magic_val); } bool fhas_fs_type(int fd, fs_type_magic magic_val) @@ -358,7 +358,7 @@ if (ret < 0) return false; - return is_fs_type(&sb, magic_val); + return lxc_is_fs_type(&sb, magic_val); } FILE *fopen_cloexec(const char *path, const char *mode) @@ -549,7 +549,7 @@ return f; } -int fd_cloexec(int fd, bool cloexec) +int lxc_fd_cloexec(int fd, bool cloexec) { int oflags, nflags; @@ -688,7 +688,7 @@ return move_fd(fd); } -int fd_make_nonblocking(int fd) +int fd_make_blocking(int fd) { int flags; @@ -700,6 +700,18 @@ return fcntl(fd, F_SETFL, flags); } +int fd_make_nonblocking(int fd) +{ + int flags; + + flags = fcntl(fd, F_GETFL); + if (flags < 0) + return -1; + + flags |= O_NONBLOCK; + return fcntl(fd, F_SETFL, flags); +} + #define BATCH_SIZE 50 static void batch_realloc(char **mem, size_t oldlen, size_t newlen) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/file_utils.h new/lxc-5.0.3/src/lxc/file_utils.h --- old/lxc-5.0.2/src/lxc/file_utils.h 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/file_utils.h 2023-07-26 00:00:11.000000000 +0200 @@ -75,7 +75,7 @@ __hidden extern bool file_exists(const char *f); __hidden extern int print_to_file(const char *file, const char *content); -__hidden extern int is_dir(const char *path); +__hidden extern int lxc_is_dir(const char *path); __hidden extern int lxc_count_file_lines(const char *fn); __hidden extern int lxc_make_tmpfile(char *template, bool rm); @@ -83,7 +83,7 @@ typedef __typeof__(((struct statfs *)NULL)->f_type) fs_type_magic; __hidden extern bool has_fs_type(const char *path, fs_type_magic magic_val); __hidden extern bool fhas_fs_type(int fd, fs_type_magic magic_val); -__hidden extern bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val); +__hidden extern bool lxc_is_fs_type(const struct statfs *fs, fs_type_magic magic_val); __hidden extern FILE *fopen_cloexec(const char *path, const char *mode); __hidden extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset, size_t count); __hidden extern char *file_to_buf(const char *path, size_t *length); @@ -93,7 +93,7 @@ { return __fd_to_fd(from, to) >= 0; } -__hidden extern int fd_cloexec(int fd, bool cloexec); +__hidden extern int lxc_fd_cloexec(int fd, bool cloexec); __hidden extern int lxc_open_dirfd(const char *dir); __hidden extern FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer); __hidden extern FILE *fdopen_at(int dfd, const char *path, const char *mode, @@ -109,6 +109,7 @@ unsigned int o_flags, unsigned int resolve_flags, mode_t mode); __hidden extern int open_beneath(int dfd, const char *path, unsigned int flags); +__hidden int fd_make_blocking(int fd); __hidden int fd_make_nonblocking(int fd); __hidden extern char *read_file_at(int dfd, const char *fnam, unsigned int o_flags, @@ -132,7 +133,7 @@ if (fd_dup < 0) return -errno; - if (fd_cloexec(fd_dup, true)) + if (lxc_fd_cloexec(fd_dup, true)) return -errno; return move_fd(fd_dup); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/initutils.c new/lxc-5.0.3/src/lxc/initutils.c --- old/lxc-5.0.2/src/lxc/initutils.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/initutils.c 2023-07-26 00:00:11.000000000 +0200 @@ -224,7 +224,7 @@ * PR_SET_MM_MAP requires us to set it all at once, so we have to * figure it out anyway. */ - unsigned long start_data, end_data, start_brk, start_code, end_code, + uint64_t start_data, end_data, start_brk, start_code, end_code, start_stack, arg_start, arg_end, env_start, env_end, brk_val; struct prctl_mm_map prctl_map; @@ -242,32 +242,35 @@ buf[bytes_read] = '\0'; - /* Skip the first 25 fields, column 26-28 are start_code, end_code, - * and start_stack */ - buf_ptr = strchr(buf, ' '); + /* + * executable names may contain spaces, so we search backwards for the + * ), which is the kernel's marker for "end of executable name". this + * puts the pointer at the end of the second field. + */ + buf_ptr = strrchr(buf, ')'); + if (!buf_ptr) + return -1; + + /* Skip the space and the next 23 fields, column 26-28 are start_code, + * end_code, and start_stack */ for (i = 0; i < 24; i++) { + buf_ptr = strchr(buf_ptr + 1, ' '); if (!buf_ptr) return -1; - buf_ptr = strchr(buf_ptr + 1, ' '); } - if (!buf_ptr) - return -1; - i = sscanf(buf_ptr, "%lu %lu %lu", &start_code, &end_code, &start_stack); + i = sscanf(buf_ptr, "%" PRIu64 " %" PRIu64 " %" PRIu64, &start_code, &end_code, &start_stack); if (i != 3) return -1; /* Skip the next 19 fields, column 45-51 are start_data to arg_end */ for (i = 0; i < 19; i++) { + buf_ptr = strchr(buf_ptr + 1, ' '); if (!buf_ptr) return -1; - buf_ptr = strchr(buf_ptr + 1, ' '); } - if (!buf_ptr) - return -1; - - i = sscanf(buf_ptr, "%lu %lu %lu %*u %*u %lu %lu", &start_data, + i = sscanf(buf_ptr, "%" PRIu64 " %" PRIu64 " %" PRIu64 " %*u %*u %" PRIu64 " %" PRIu64, &start_data, &end_data, &start_brk, &env_start, &env_end); if (i != 5) return -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/lsm/apparmor.c new/lxc-5.0.3/src/lxc/lsm/apparmor.c --- old/lxc-5.0.2/src/lxc/lsm/apparmor.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/lsm/apparmor.c 2023-07-26 00:00:11.000000000 +0200 @@ -973,12 +973,14 @@ goto out; } old_len = profile_sb.st_size; - old_content = lxc_strmmap(NULL, old_len, PROT_READ, - MAP_PRIVATE, profile_fd, 0); - if (old_content == MAP_FAILED) { - SYSERROR("Failed to mmap old profile from %s", - profile_path); - goto out; + if (old_len) { + old_content = lxc_strmmap(NULL, old_len, PROT_READ, + MAP_PRIVATE, profile_fd, 0); + if (old_content == MAP_FAILED) { + SYSERROR("Failed to mmap old profile from %s", + profile_path); + goto out; + } } } else if (errno != ENOENT) { SYSERROR("Error reading old profile from %s", profile_path); @@ -994,14 +996,14 @@ if (!old_content || old_len != content_len || memcmp(old_content, new_content, content_len) != 0) { char *path; - ret = mkdir_p(APPARMOR_CACHE_DIR, 0755); + ret = lxc_mkdir_p(APPARMOR_CACHE_DIR, 0755); if (ret < 0) { SYSERROR("Error creating AppArmor profile cache directory " APPARMOR_CACHE_DIR); goto out; } path = apparmor_dir(conf->name, lxcpath); - ret = mkdir_p(path, 0755); + ret = lxc_mkdir_p(path, 0755); if (ret < 0) { SYSERROR("Error creating AppArmor profile directory: %s", path); free(path); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/lxccontainer.c new/lxc-5.0.3/src/lxc/lxccontainer.c --- old/lxc-5.0.2/src/lxc/lxccontainer.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/lxccontainer.c 2023-07-26 00:00:11.000000000 +0200 @@ -4159,7 +4159,7 @@ i = get_next_index(snappath, c->name); - if (mkdir_p(snappath, 0755) < 0) { + if (lxc_mkdir_p(snappath, 0755) < 0) { ERROR("Failed to create snapshot directory %s", snappath); return -1; } @@ -4174,7 +4174,7 @@ */ flags = LXC_CLONE_SNAPSHOT | LXC_CLONE_KEEPMACADDR | LXC_CLONE_KEEPNAME | LXC_CLONE_KEEPBDEVTYPE | LXC_CLONE_MAYBE_SNAPSHOT; - if (storage_is_dir(c->lxc_conf)) { + if (storage_lxc_is_dir(c->lxc_conf)) { ERROR("Snapshot of directory-backed container requested"); ERROR("Making a copy-clone. If you do want snapshots, then"); ERROR("please create overlay clone first, snapshot that"); @@ -4608,7 +4608,7 @@ _exit(EXIT_FAILURE); directory_path = dirname(tmp); - ret = mkdir_p(directory_path, 0755); + ret = lxc_mkdir_p(directory_path, 0755); if (ret < 0 && errno != EEXIST) { SYSERROR("Failed to create path \"%s\"", directory_path); free(tmp); @@ -4978,7 +4978,7 @@ } destdirname = dirname(dirdup); - ret = mkdir_p(destdirname, 0755); + ret = lxc_mkdir_p(destdirname, 0755); if (ret < 0) { SYSERROR("Failed to create \"%s\"", destdirname); free(dirdup); @@ -5012,7 +5012,7 @@ char template[PATH_MAX], path[PATH_MAX]; pid_t pid, init_pid; struct stat sb; - bool is_dir; + bool lxc_is_dir; int ret = -1, fd = -EBADF; if (!c || !c->lxc_conf) { @@ -5043,8 +5043,8 @@ } } - is_dir = (S_ISDIR(sb.st_mode) != 0); - if (is_dir) { + lxc_is_dir = (S_ISDIR(sb.st_mode) != 0); + if (lxc_is_dir) { sret = mkdtemp(template); if (!sret) { SYSERROR("Could not create shmounts temporary dir"); @@ -5133,7 +5133,7 @@ if (umount2(template, MNT_DETACH)) SYSWARN("Failed to remove temporary mount \"%s\"", template); - if (is_dir) + if (lxc_is_dir) (void)rmdir(template); else (void)unlink(template); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/lxclock.c new/lxc-5.0.3/src/lxc/lxclock.c --- old/lxc-5.0.2/src/lxc/lxclock.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/lxclock.c 2023-07-26 00:00:11.000000000 +0200 @@ -105,7 +105,7 @@ if (ret < 0) return NULL; - ret = mkdir_p(dest, 0755); + ret = lxc_mkdir_p(dest, 0755); if (ret < 0) return NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/mainloop.c new/lxc-5.0.3/src/lxc/mainloop.c --- old/lxc-5.0.2/src/lxc/mainloop.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/mainloop.c 2023-07-26 00:00:11.000000000 +0200 @@ -163,6 +163,16 @@ io_uring_prep_poll_add(sqe, handler->fd, EPOLLIN); /* + * FIXME: workaround an issue with false-positive + * io_uring POLL events when multishot mode is enabled. + * + * It's safe to override oneshot argument here, execution + * will go to the same codepath as if kernel lacks IORING_POLL_ADD_MULTI + * mode support. + */ + oneshot = true; + + /* * Raise IORING_POLL_ADD_MULTI to set up a multishot poll. The same sqe * will now produce multiple cqes. A cqe produced from a multishot sqe * will raise IORING_CQE_F_MORE in cqe->flags. @@ -205,7 +215,7 @@ return syserror_set(ENOENT, "Failed to get submission queue entry"); - io_uring_prep_poll_remove(sqe, handler); + io_uring_prep_poll_remove(sqe, PTR_TO_U64(handler)); io_uring_sqe_set_data(sqe, handler); ret = io_uring_submit(descr->ring); if (ret < 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/monitor.c new/lxc-5.0.3/src/lxc/monitor.c --- old/lxc-5.0.2/src/lxc/monitor.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/monitor.c 2023-07-26 00:00:11.000000000 +0200 @@ -54,7 +54,7 @@ free(rundir); return -1; } - ret = mkdir_p(fifo_path, 0755); + ret = lxc_mkdir_p(fifo_path, 0755); if (ret < 0) { ERROR("Unable to create monitor fifo directory %s", fifo_path); free(rundir); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/pam/pam_cgfs.c new/lxc-5.0.3/src/lxc/pam/pam_cgfs.c --- old/lxc-5.0.2/src/lxc/pam/pam_cgfs.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/pam/pam_cgfs.c 2023-07-26 00:00:11.000000000 +0200 @@ -197,7 +197,7 @@ } /* Create directory and (if necessary) its parents. */ -static bool mkdir_parent(const char *root, char *path) +static bool lxc_mkdir_parent(const char *root, char *path) { char *b, orig, *e; @@ -2042,7 +2042,7 @@ return our_cg; } - created = mkdir_parent(it->mountpoint, path); + created = lxc_mkdir_parent(it->mountpoint, path); if (!created) { free(path); continue; @@ -2198,7 +2198,7 @@ } } - created = mkdir_parent(v2->mountpoint, path); + created = lxc_mkdir_parent(v2->mountpoint, path); if (!created) { free(path); return false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/seccomp.c new/lxc-5.0.3/src/lxc/seccomp.c --- old/lxc-5.0.2/src/lxc/seccomp.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/seccomp.c 2023-07-26 00:00:11.000000000 +0200 @@ -1282,8 +1282,8 @@ return -1; } - if (fd_make_nonblocking(ret)) - return log_error_errno(-1, errno, "Failed to make seccomp listener fd non-blocking");; + if (fd_make_blocking(ret)) + return log_error_errno(-1, errno, "Failed to make seccomp listener fd blocking"); conf->seccomp.notifier.notify_fd = ret; TRACE("Retrieved new seccomp listener fd %d", ret); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/storage/dir.c new/lxc-5.0.3/src/lxc/storage/dir.c --- old/lxc-5.0.2/src/lxc/storage/dir.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/storage/dir.c 2023-07-26 00:00:11.000000000 +0200 @@ -81,7 +81,7 @@ if (!bdev_dest) return ret_errno(ENOMEM); - ret = mkdir_p(dest, 0755); + ret = lxc_mkdir_p(dest, 0755); if (ret < 0) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", dest); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/storage/loop.c new/lxc-5.0.3/src/lxc/storage/loop.c --- old/lxc-5.0.2/src/lxc/storage/loop.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/storage/loop.c 2023-07-26 00:00:11.000000000 +0200 @@ -165,7 +165,7 @@ return -1; } - ret = mkdir_p(bdev->dest, 0755); + ret = lxc_mkdir_p(bdev->dest, 0755); if (ret < 0) { ERROR("Failed creating directory \"%s\"", bdev->dest); return -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/storage/lvm.c new/lxc-5.0.3/src/lxc/storage/lvm.c --- old/lxc-5.0.2/src/lxc/storage/lvm.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/storage/lvm.c 2023-07-26 00:00:11.000000000 +0200 @@ -456,7 +456,7 @@ return -1; } - ret = mkdir_p(new->dest, 0755); + ret = lxc_mkdir_p(new->dest, 0755); if (ret < 0) { SYSERROR("Failed to create directory \"%s\"", new->dest); return -1; @@ -645,7 +645,7 @@ return -1; } - ret = mkdir_p(bdev->dest, 0755); + ret = lxc_mkdir_p(bdev->dest, 0755); if (ret < 0) { SYSERROR("Failed to create directory \"%s\"", bdev->dest); return -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/storage/overlay.c new/lxc-5.0.3/src/lxc/storage/overlay.c --- old/lxc-5.0.2/src/lxc/storage/overlay.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/storage/overlay.c 2023-07-26 00:00:11.000000000 +0200 @@ -50,7 +50,7 @@ new->dest = must_make_path(lxcpath, cname, "rootfs", NULL); - ret = mkdir_p(new->dest, 0755); + ret = lxc_mkdir_p(new->dest, 0755); if (ret < 0 && errno != EEXIST) { SYSERROR("Failed to create directory \"%s\"", new->dest); return -1; @@ -68,7 +68,7 @@ delta = must_make_path(lxcpath, cname, LXC_OVERLAY_DELTA_PATH, NULL); - ret = mkdir_p(delta, 0755); + ret = lxc_mkdir_p(delta, 0755); if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", delta); @@ -83,7 +83,7 @@ */ work = must_make_path(lxcpath, cname, LXC_OVERLAY_WORK_PATH, NULL); - ret = mkdir_p(work, 0755); + ret = lxc_mkdir_p(work, 0755); if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", work); @@ -142,7 +142,7 @@ odelta++; ndelta = must_make_path(lxcpath, cname, LXC_OVERLAY_DELTA_PATH, NULL); - ret = mkdir_p(ndelta, 0755); + ret = lxc_mkdir_p(ndelta, 0755); if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", ndelta); @@ -150,7 +150,7 @@ * further up.). */ work = must_make_path(lxcpath, cname, LXC_OVERLAY_WORK_PATH, NULL); - ret = mkdir_p(work, 0755); + ret = lxc_mkdir_p(work, 0755); if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", ndelta); @@ -191,11 +191,11 @@ * don't need to record a dependency. If we would restore would * also fail. */ - clean_old_path = path_simplify(oldpath); + clean_old_path = lxc_path_simplify(oldpath); if (!clean_old_path) return log_error_errno(-ENOMEM, ENOMEM, "Failed to create clean path for \"%s\"", oldpath); - clean_new_path = path_simplify(lxcpath); + clean_new_path = lxc_path_simplify(lxcpath); if (!clean_new_path) return log_error_errno(-ENOMEM, ENOMEM, "Failed to create clean path for \"%s\"", lxcpath); @@ -271,7 +271,7 @@ delta = must_make_path(tmp, LXC_OVERLAY_DELTA_PATH, NULL); - ret = mkdir_p(delta, 0755); + ret = lxc_mkdir_p(delta, 0755); if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", delta); @@ -298,7 +298,7 @@ if (ret < 0 || (size_t)ret >= len) return log_error_errno(-EIO, EIO, "Failed to create rootfs path"); - ret = mkdir_p(bdev->dest, 0755); + ret = lxc_mkdir_p(bdev->dest, 0755); if (ret < 0 && errno != EEXIST) return log_error_errno(-errno, errno, "Failed to create directory \"%s\"", bdev->dest); @@ -389,7 +389,7 @@ upper++; /* if delta doesn't yet exist, create it */ - ret = mkdir_p(upper, 0755); + ret = lxc_mkdir_p(upper, 0755); if (ret < 0 && errno != EEXIST) { SYSERROR("Failed to create directory \"%s\"", upper); free(dup); @@ -422,7 +422,7 @@ return -22; } - ret = mkdir_p(work, 0755); + ret = lxc_mkdir_p(work, 0755); if (ret < 0 && errno != EEXIST) { SYSERROR("Failed to create directory \"%s\"", work); free(mntdata); @@ -623,10 +623,10 @@ ret = 0; if (upperdir) { if (!rootfs_path) - ret = mkdir_p(upperdir, 0755); + ret = lxc_mkdir_p(upperdir, 0755); else if (!strncmp(upperdir, lxcpath, dirlen) && strncmp(upperdir, rootfs_dir, rootfslen)) - ret = mkdir_p(upperdir, 0755); + ret = lxc_mkdir_p(upperdir, 0755); if (ret < 0) SYSWARN("Failed to create directory \"%s\"", upperdir); @@ -635,10 +635,10 @@ ret = 0; if (workdir) { if (!rootfs_path) - ret = mkdir_p(workdir, 0755); + ret = lxc_mkdir_p(workdir, 0755); else if (!strncmp(workdir, lxcpath, dirlen) && strncmp(workdir, rootfs_dir, rootfslen)) - ret = mkdir_p(workdir, 0755); + ret = lxc_mkdir_p(workdir, 0755); if (ret < 0) SYSWARN("Failed to create directory \"%s\"", workdir); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/storage/rbd.c new/lxc-5.0.3/src/lxc/storage/rbd.c --- old/lxc-5.0.2/src/lxc/storage/rbd.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/storage/rbd.c 2023-07-26 00:00:11.000000000 +0200 @@ -160,7 +160,7 @@ return -1; } - ret = mkdir_p(bdev->dest, 0755); + ret = lxc_mkdir_p(bdev->dest, 0755); if (ret < 0 && errno != EEXIST) { ERROR("Failed to create directory \"%s\"", bdev->dest); return -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/storage/storage.c new/lxc-5.0.3/src/lxc/storage/storage.c --- old/lxc-5.0.2/src/lxc/storage/storage.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/storage/storage.c 2023-07-26 00:00:11.000000000 +0200 @@ -370,7 +370,7 @@ ret = stat(orig->dest, &sb); if (ret < 0 && errno == ENOENT) { - ret = mkdir_p(orig->dest, 0755); + ret = lxc_mkdir_p(orig->dest, 0755); if (ret < 0) WARN("Failed to create directory \"%s\"", orig->dest); } @@ -638,7 +638,7 @@ return bdev; } -bool storage_is_dir(struct lxc_conf *conf) +bool storage_lxc_is_dir(struct lxc_conf *conf) { struct lxc_storage *orig; char *type = conf->rootfs.bdev_type; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/storage/storage.h new/lxc-5.0.3/src/lxc/storage/storage.h --- old/lxc-5.0.2/src/lxc/storage/storage.h 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/storage/storage.h 2023-07-26 00:00:11.000000000 +0200 @@ -94,7 +94,7 @@ }; /** - * storage_is_dir : Check whether the roots is a directory. This function will + * storage_lxc_is_dir : Check whether the roots is a directory. This function will * trust the config file. If the config file key * lxc.rootfs.path is set to <storage type>:<container path> * the confile parser will have split this into <storage type> @@ -105,7 +105,7 @@ * type specifications. If the <storage type> prefix is not * detected liblxc will try to detect the storage type. */ -__hidden extern bool storage_is_dir(struct lxc_conf *conf); +__hidden extern bool storage_lxc_is_dir(struct lxc_conf *conf); __hidden extern bool storage_can_backup(struct lxc_conf *conf); __hidden extern struct lxc_storage *storage_init(struct lxc_conf *conf); __hidden extern struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/storage/zfs.c new/lxc-5.0.3/src/lxc/storage/zfs.c --- old/lxc-5.0.2/src/lxc/storage/zfs.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/storage/zfs.c 2023-07-26 00:00:11.000000000 +0200 @@ -293,7 +293,7 @@ TRACE("Created zfs dataset \"%s\"", new->src); } - ret = mkdir_p(new->dest, 0755); + ret = lxc_mkdir_p(new->dest, 0755); if (ret < 0 && errno != EEXIST) { SYSERROR("Failed to create directory \"%s\"", new->dest); return false; @@ -542,7 +542,7 @@ return -1; } - ret = mkdir_p(new->dest, 0755); + ret = lxc_mkdir_p(new->dest, 0755); if (ret < 0 && errno != EEXIST) { SYSERROR("Failed to create directory \"%s\"", new->dest); return -1; @@ -740,7 +740,7 @@ TRACE("Created zfs dataset \"%s\"", bdev->src); } - ret = mkdir_p(bdev->dest, 0755); + ret = lxc_mkdir_p(bdev->dest, 0755); if (ret < 0 && errno != EEXIST) { SYSERROR("Failed to create directory \"%s\"", bdev->dest); return -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/string_utils.c new/lxc-5.0.3/src/lxc/string_utils.c --- old/lxc-5.0.2/src/lxc/string_utils.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/string_utils.c 2023-07-26 00:00:11.000000000 +0200 @@ -187,7 +187,7 @@ } /* taken from systemd */ -char *path_simplify(const char *path) +char *lxc_path_simplify(const char *path) { __do_free char *path_new = NULL; char *f, *t; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/string_utils.h new/lxc-5.0.3/src/lxc/string_utils.h --- old/lxc-5.0.2/src/lxc/string_utils.h 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/string_utils.h 2023-07-26 00:00:11.000000000 +0200 @@ -188,6 +188,6 @@ (__iterator = __it); \ __iterator = __it = strtok_r(NULL, __separators, &__p)) -__hidden extern char *path_simplify(const char *path); +__hidden extern char *lxc_path_simplify(const char *path); #endif /* __LXC_STRING_UTILS_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/terminal.c new/lxc-5.0.3/src/lxc/terminal.c --- old/lxc-5.0.2/src/lxc/terminal.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/terminal.c 2023-07-26 00:00:11.000000000 +0200 @@ -334,9 +334,12 @@ int r, w, w_log, w_rbuf; w = r = lxc_read_nointr(terminal->ptx, buf, sizeof(buf)); - if (r <= 0) - return -1; + if (r <= 0) { + if (errno == EWOULDBLOCK) + return 0; + return -1; + } w_rbuf = w_log = 0; /* write to peer first */ if (terminal->peer >= 0) @@ -370,8 +373,12 @@ int r, w; w = r = lxc_read_nointr(terminal->peer, buf, sizeof(buf)); - if (r <= 0) + if (r <= 0) { + if (errno == EWOULDBLOCK) + return 0; + return -1; + } w = lxc_write_nointr(terminal->ptx, buf, r); if (w != r) @@ -415,6 +422,9 @@ int ret; if (terminal->peer >= 0) { + if (fd_make_nonblocking(terminal->peer)) + return log_error_errno(-1, errno, "Failed to make terminal peer fd non-blocking"); + ret = lxc_mainloop_add_handler(terminal->descr, terminal->peer, lxc_terminal_peer_io_handler, default_cleanup_handler, @@ -452,6 +462,9 @@ return 0; } + if (fd_make_nonblocking(terminal->ptx)) + return log_error_errno(-1, errno, "Failed to make terminal ptx fd non-blocking"); + ret = lxc_mainloop_add_handler(descr, terminal->ptx, lxc_terminal_ptx_io_handler, default_cleanup_handler, @@ -577,13 +590,13 @@ goto on_error; } - ret = fd_cloexec(terminal->proxy.ptx, true); + ret = lxc_fd_cloexec(terminal->proxy.ptx, true); if (ret < 0) { SYSERROR("Failed to set FD_CLOEXEC flag on proxy terminal ptx"); goto on_error; } - ret = fd_cloexec(terminal->proxy.pty, true); + ret = lxc_fd_cloexec(terminal->proxy.pty, true); if (ret < 0) { SYSERROR("Failed to set FD_CLOEXEC flag on proxy terminal pty"); goto on_error; @@ -917,13 +930,13 @@ goto err; } - ret = fd_cloexec(terminal->ptx, true); + ret = lxc_fd_cloexec(terminal->ptx, true); if (ret < 0) { SYSERROR("Failed to set FD_CLOEXEC flag on terminal ptx"); goto err; } - ret = fd_cloexec(terminal->pty, true); + ret = lxc_fd_cloexec(terminal->pty, true); if (ret < 0) { SYSERROR("Failed to set FD_CLOEXEC flag on terminal pty"); goto err; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/tools/lxc_copy.c new/lxc-5.0.3/src/lxc/tools/lxc_copy.c --- old/lxc-5.0.2/src/lxc/tools/lxc_copy.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/tools/lxc_copy.c 2023-07-26 00:00:11.000000000 +0200 @@ -358,7 +358,7 @@ goto err; } else if (m->mnt_type == LXC_MNT_BIND) { len = strlen(" none bind,optional,, 0 0") + - strlen(is_dir(m->src) ? "create=dir" : "create=file") + + strlen(lxc_is_dir(m->src) ? "create=dir" : "create=file") + strlen(m->src) + strlen(m->dest) + strlen(m->options) + 1; mntentry = malloc(len); @@ -367,7 +367,7 @@ ret = snprintf(mntentry, len, "%s %s none bind,optional,%s,%s 0 0", m->src, m->dest, m->options, - is_dir(m->src) ? "create=dir" : "create=file"); + lxc_is_dir(m->src) ? "create=dir" : "create=file"); if (ret < 0 || (size_t)ret >= len) goto err; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/tools/lxc_create.c new/lxc-5.0.3/src/lxc/tools/lxc_create.c --- old/lxc-5.0.2/src/lxc/tools/lxc_create.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/tools/lxc_create.c 2023-07-26 00:00:11.000000000 +0200 @@ -244,7 +244,7 @@ if (!my_args.lxcpath[0]) my_args.lxcpath[0] = lxc_get_global_config_item("lxc.lxcpath"); - if (mkdir_p(my_args.lxcpath[0], 0755)) + if (lxc_mkdir_p(my_args.lxcpath[0], 0755)) exit(EXIT_FAILURE); if (geteuid()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/utils.c new/lxc-5.0.3/src/lxc/utils.c --- old/lxc-5.0.2/src/lxc/utils.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/utils.c 2023-07-26 00:00:11.000000000 +0200 @@ -212,7 +212,7 @@ return 0; } -int mkdir_p(const char *dir, mode_t mode) +int lxc_mkdir_p(const char *dir, mode_t mode) { const char *tmp = dir; const char *orig = dir; @@ -1690,7 +1690,7 @@ if (dupfd < 0) return -1; - if (fd_cloexec(dupfd, true) < 0) + if (lxc_fd_cloexec(dupfd, true) < 0) return -1; f = fdopen(dupfd, "re"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/lxc/utils.h new/lxc-5.0.3/src/lxc/utils.h --- old/lxc-5.0.2/src/lxc/utils.h 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/lxc/utils.h 2023-07-26 00:00:11.000000000 +0200 @@ -26,7 +26,7 @@ /* returns 1 on success, 0 if there were any failures */ __hidden extern int lxc_rmdir_onedev(const char *path, const char *exclude); __hidden extern int get_u16(unsigned short *val, const char *arg, int base); -__hidden extern int mkdir_p(const char *dir, mode_t mode); +__hidden extern int lxc_mkdir_p(const char *dir, mode_t mode); __hidden extern char *get_rundir(void); /* Define getline() if missing from the C library */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/tests/console_log.c new/lxc-5.0.3/src/tests/console_log.c --- old/lxc-5.0.2/src/tests/console_log.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/tests/console_log.c 2023-07-26 00:00:11.000000000 +0200 @@ -133,6 +133,11 @@ goto on_error_stop; } + if (!c->wait(c, "STOPPED", 5)) { + lxc_error("%s\n", "Failed waiting for container \"console-log\" to stop"); + goto on_error_stop; + } + c->clear_config(c); if (!c->load_config(c, NULL)) { @@ -165,6 +170,11 @@ goto on_error_stop; } + if (!c->wait(c, "STOPPED", 5)) { + lxc_error("%s\n", "Failed waiting for container \"console-log\" to stop"); + goto on_error_stop; + } + if (!c->startl(c, 0, NULL)) { lxc_error("%s\n", "Failed to start container \"console-log\" daemonized"); goto on_error_destroy; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/tests/createtest.c new/lxc-5.0.3/src/tests/createtest.c --- old/lxc-5.0.2/src/tests/createtest.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/tests/createtest.c 2023-07-26 00:00:11.000000000 +0200 @@ -56,7 +56,7 @@ c->set_config_item(c, "lxc.net.0.flags", "up"); if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) { - fprintf(stderr, "%d: failed to create a trusty container\n", __LINE__); + fprintf(stderr, "%d: failed to create a container\n", __LINE__); goto out; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/tests/get_item.c new/lxc-5.0.3/src/tests/get_item.c --- old/lxc-5.0.2/src/tests/get_item.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/tests/get_item.c 2023-07-26 00:00:11.000000000 +0200 @@ -509,7 +509,7 @@ } if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) { - fprintf(stderr, "%d: failed to create a trusty container\n", __LINE__); + fprintf(stderr, "%d: failed to create a container\n", __LINE__); goto out; } lxc_container_put(c); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/tests/lxc-test-fuzzers new/lxc-5.0.3/src/tests/lxc-test-fuzzers --- old/lxc-5.0.2/src/tests/lxc-test-fuzzers 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/tests/lxc-test-fuzzers 1970-01-01 01:00:00.000000000 +0100 @@ -1,25 +0,0 @@ -#!/bin/bash - -set -eux -set -o pipefail - -TMP_DIR=$(mktemp -d) -export ASAN_OPTIONS=${ASAN_OPTIONS:-detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:strict_string_checks=1} -export UBSAN_OPTIONS=${UBSAN_OPTIONS:-print_stacktrace=1:print_summary=1:halt_on_error=1} - -cleanup() { - rm -rf "$TMP_DIR" -} - -trap cleanup exit - -for fuzzer in /usr/bin/fuzz-lxc-*; do - name=$(basename "$fuzzer") - corpus_dir="$TMP_DIR/$name" - - mkdir -p "$corpus_dir" - if wget --directory-prefix="$TMP_DIR" https://storage.googleapis.com/lxc-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/lxc_$name/public.zip; then - unzip -q -d "$corpus_dir" "$TMP_DIR/public.zip" - fi - "$fuzzer" -max_total_time=120 "$corpus_dir" -done diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/tests/lxc-test-utils.c new/lxc-5.0.3/src/tests/lxc-test-utils.c --- old/lxc-5.0.2/src/tests/lxc-test-utils.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/tests/lxc-test-utils.c 2023-07-26 00:00:11.000000000 +0200 @@ -43,12 +43,12 @@ #include "macro.h" #include "utils.h" -void test_path_simplify(void) +void test_lxc_path_simplify(void) { char *s = "/A///B//C/D/E/"; char *t; - t = path_simplify(s); + t = lxc_path_simplify(s); if (!t) exit(EXIT_FAILURE); @@ -57,7 +57,7 @@ s = "/A"; - t = path_simplify(s); + t = lxc_path_simplify(s); if (!t) exit(EXIT_FAILURE); @@ -65,7 +65,7 @@ free(t); s = ""; - t = path_simplify(s); + t = lxc_path_simplify(s); if (!t) exit(EXIT_FAILURE); @@ -74,7 +74,7 @@ s = "//"; - t = path_simplify(s); + t = lxc_path_simplify(s); if (!t) exit(EXIT_FAILURE); @@ -607,7 +607,7 @@ { test_lxc_string_replace(); test_lxc_string_in_array(); - test_path_simplify(); + test_lxc_path_simplify(); test_detect_ramfs_rootfs(); test_lxc_safe_uint(); test_lxc_safe_int(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/tests/mount_injection.c new/lxc-5.0.3/src/tests/mount_injection.c --- old/lxc-5.0.2/src/tests/mount_injection.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/tests/mount_injection.c 2023-07-26 00:00:11.000000000 +0200 @@ -391,7 +391,7 @@ { int ret; - ret = mkdir_p(shmount_path, 0711); + ret = lxc_mkdir_p(shmount_path, 0711); if (ret < 0 && errno != EEXIST) { fprintf(stderr, "Failed to create directory \"%s\"\n", shmount_path); return false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/src/tests/parse_config_file.c new/lxc-5.0.3/src/tests/parse_config_file.c --- old/lxc-5.0.2/src/tests/parse_config_file.c 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/src/tests/parse_config_file.c 2023-07-26 00:00:11.000000000 +0200 @@ -576,7 +576,14 @@ goto non_test_error; } - if (set_get_compare_clear_save_load(c, "lxc.seccomp.profile", "/some/seccomp/file", tmpf, true) < 0) { + ret = set_get_compare_clear_save_load(c, "lxc.seccomp.profile", "/some/seccomp/file", tmpf, true); + +#if HAVE_SECCOMP + if (ret < 0) +#else + if (ret == 0) +#endif + { lxc_error("%s\n", "lxc.seccomp.profile"); goto non_test_error; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lxc-5.0.2/templates/lxc-oci.in new/lxc-5.0.3/templates/lxc-oci.in --- old/lxc-5.0.2/templates/lxc-oci.in 2023-01-16 22:08:50.000000000 +0100 +++ new/lxc-5.0.3/templates/lxc-oci.in 2023-07-26 00:00:11.000000000 +0200 @@ -36,16 +36,19 @@ LOCALSTATEDIR=@LOCALSTATEDIR@ LXC_TEMPLATE_CONFIG=@LXCTEMPLATECONFIG@ LXC_HOOK_DIR=@LXCHOOKDIR@ +MOUNT_HELPER="atomfs" +MOUNTED_WORKDIR="" # Some useful functions cleanup() { - if [ -d "${DOWNLOAD_TEMP}" ]; then - rm -Rf "${DOWNLOAD_TEMP}" - fi - if [ -d "${LXC_ROOTFS}.tmp" ]; then rm -Rf "${LXC_ROOTFS}.tmp" fi + if [ -n "${MOUNTED_WORKDIR}" ]; then + echo "${MOUNT_HELPER} unmount ${MOUNTED_WORKDIR}" >&2 + "${MOUNT_HELPER}" umount "${MOUNTED_WORKDIR}" + MOUNTED_WORKDIR="" + fi } in_userns() { @@ -72,28 +75,50 @@ } getconfigpath() { - basedir="$1" - q="$2" - - digest=$(jq -c -r --arg q "$q" '.manifests[] | if .annotations."org.opencontainers.image.ref.name" == $q then .digest else empty end' < "${basedir}/index.json") - if [ -z "${digest}" ]; then - echo "$q not found in index.json" >&2 - return - fi - - # Ok we have the image config digest, now get the config from that + local basedir="$1" mfpath="$2" cdigest="" + # Ok we have the image config digest, now get the config ref from the manifest. # shellcheck disable=SC2039 - d=${digest:7} - cdigest=$(jq -c -r '.config.digest' < "${basedir}/blobs/sha256/${d}") + cdigest=$(jq -c -r '.config.digest' < "$mfpath") if [ -z "${cdigest}" ]; then echo "container config not found" >&2 return fi - # shellcheck disable=SC2039 - d2=${cdigest:7} - echo "${basedir}/blobs/sha256/${d2}" - return + # cdigest is '<hashtype>:<hash>', so 'ht' gets type, hv gets value. + local ht="${cdigest%%:*}" hv="${cdigest#*:}" p="" + p="$basedir/blobs/$ht/$hv" + if [ ! -f "$p" ]; then + echo "config file did not exist for digest $cdigest" >&2 + return 1 + fi + echo "$p" +} + +getmanifestpath() { + local basedir="$1" ref="$2" p="" + # if given 'sha256:<hash>' then return the blobs/sha256/hash + case "$ref" in + sha256:*) + p="$basedir/blobs/sha256/${ref#sha256:}" + [ -f "$p" ] && echo "$p" && return 0 + echo "could not find manifest path to blob $ref. file did not exist: $p" >&2 + return 1 + ;; + esac + # find the reference by annotation + local blobref="" hashtype="" hashval="" + blobref=$(jq -c -r --arg q "$ref" '.manifests[] | if .annotations."org.opencontainers.image.ref.name" == $q then .digest else empty end' < "${basedir}/index.json") + # blobref is 'hashtype:hash' + hashtype="${blobref%%:*}" + hashval="${blobref#*:}" + p="$basedir/blobs/$hashtype/$hashval" + [ -f "$p" ] && echo "$p" && return 0 + echo "did not find manifest for $ref. file did not exist: $p" >&2 + return 1 +} + +getlayermediatype() { + jq -c -r '.layers[0].mediaType' <"$1" } # Get entrypoint from oci image. Use sh if unspecified @@ -211,6 +236,13 @@ Optional arguments: [ --username <username> ]: The username for the registry [ --password <password> ]: The password for the registry +[ --mount-helper <command> ]: program that will be used to mount. default is 'atomfs' + + mount-helper is expected to support being called with 'mount' + and 'umount' subcommands as below: + + mount-helper mount oci:<oci_dir>:<oci_name> <mountpoint> + mount-helper umount <mountpoint> LXC internal arguments (do not pass manually!): [ --name <name> ]: The container name @@ -222,7 +254,7 @@ return 0 } -if ! options=$(getopt -o u:h -l help,url:,username:,password:,no-cache,dhcp,name:,path:,rootfs:,mapped-uid:,mapped-gid: -- "$@"); then +if ! options=$(getopt -o u:h -l help,url:,username:,password:,no-cache,dhcp,name:,path:,rootfs:,mapped-uid:,mapped-gid:,mount-helper: -- "$@"); then usage exit 1 fi @@ -253,6 +285,7 @@ --rootfs) LXC_ROOTFS=$2; shift 2;; --mapped-uid) LXC_MAPPED_UID=$2; shift 2;; --mapped-gid) LXC_MAPPED_GID=$2; shift 2;; + --mount-helper) MOUNT_HELPER=$2; shift 2;; *) break;; esac done @@ -289,6 +322,7 @@ fi fi +OCI_DIR="$LXC_PATH/oci" if [ "${OCI_USE_CACHE}" = "true" ]; then if [ "$USERNS" = "yes" ]; then DOWNLOAD_BASE="${HOME}/.cache/lxc" @@ -296,23 +330,16 @@ DOWNLOAD_BASE="${LOCALSTATEDIR}/cache/lxc" fi else - DOWNLOAD_BASE=/tmp + DOWNLOAD_BASE="$OCI_DIR" fi mkdir -p "${DOWNLOAD_BASE}" # Trap all exit signals trap cleanup EXIT HUP INT TERM -if ! command -v mktemp >/dev/null 2>&1; then - DOWNLOAD_TEMP="${DOWNLOAD_BASE}/lxc-oci.$$" - mkdir -p "${DOWNLOAD_TEMP}" -else - DOWNLOAD_TEMP=$(mktemp -d -p "${DOWNLOAD_BASE}") -fi - # Download the image # shellcheck disable=SC2039 -skopeo_args=("") +skopeo_args=("--remove-signatures" "--insecure-policy") if [ -n "$OCI_USERNAME" ]; then CREDENTIALS="${OCI_USERNAME}" @@ -324,38 +351,66 @@ skopeo_args+=(--src-creds "${CREDENTIALS}") fi +OCI_NAME="$LXC_NAME" if [ "${OCI_USE_CACHE}" = "true" ]; then - # shellcheck disable=SC2039 - # shellcheck disable=SC2068 skopeo_args+=(--dest-shared-blob-dir "${DOWNLOAD_BASE}") - # shellcheck disable=SC2039 - # shellcheck disable=SC2068 - skopeo copy ${skopeo_args[@]} "${OCI_URL}" "oci:${DOWNLOAD_TEMP}:latest" - ln -s "${DOWNLOAD_BASE}/sha256" "${DOWNLOAD_TEMP}/blobs/sha256" -else - # shellcheck disable=SC2039 - # shellcheck disable=SC2068 - skopeo copy ${skopeo_args[@]} "${OCI_URL}" "oci:${DOWNLOAD_TEMP}:latest" + mkdir -p "${OCI_DIR}/blobs/" + ln -s "${DOWNLOAD_BASE}/sha256" "${OCI_DIR}/blobs/sha256" fi -echo "Unpacking the rootfs" -# shellcheck disable=SC2039 -umoci_args=("") -if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then - # shellcheck disable=SC2039 - umoci_args+=(--rootless) -fi -# shellcheck disable=SC2039 -# shellcheck disable=SC2068 -umoci --log=error unpack ${umoci_args[@]} --image "${DOWNLOAD_TEMP}:latest" "${LXC_ROOTFS}.tmp" -find "${LXC_ROOTFS}.tmp/rootfs" -mindepth 1 -maxdepth 1 -exec mv '{}' "${LXC_ROOTFS}/" \; +skopeo copy "${skopeo_args[@]}" "${OCI_URL}" "oci:${OCI_DIR}:${OCI_NAME}" + +mfpath=$(getmanifestpath "${OCI_DIR}" "${OCI_NAME}") +OCI_CONF_FILE=$(getconfigpath "${OCI_DIR}" "$mfpath") +mediatype=$(getlayermediatype "$mfpath") +echo "mfpath=$mfpath conf=$OCI_CONF_FILE" 1>&2 +echo "mediatype=$mediatype" >&2 + +case "$mediatype" in + #application/vnd.oci.image.layer.v1.tar+gzip + application/vnd.oci.image.layer.v1.tar*) + echo "Unpacking tar rootfs" 2>&1 + # shellcheck disable=SC2039 + umoci_args=("") + if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then + # shellcheck disable=SC2039 + umoci_args+=(--rootless) + fi + # shellcheck disable=SC2039 + # shellcheck disable=SC2068 + umoci --log=error unpack ${umoci_args[@]} --image "${OCI_DIR}:${OCI_NAME}" "${LXC_ROOTFS}.tmp" + find "${LXC_ROOTFS}.tmp/rootfs" -mindepth 1 -maxdepth 1 -exec mv '{}' "${LXC_ROOTFS}/" \; + ;; + #application/vnd.stacker.image.layer.squashfs+zstd+verity + application/vnd.*.image.layer.squashfs*) + if ! command -v "${MOUNT_HELPER}" >/dev/null 2>&1; then + echo "media type $mediatype requires $MOUNT_HELPER" >&2 + exit 1 + fi + echo "$MOUNT_HELPER mount ${OCI_DIR}:${OCI_NAME} $LXC_ROOTFS" >&2 + "$MOUNT_HELPER" mount "${OCI_DIR}:${OCI_NAME}" "$LXC_ROOTFS" + MOUNTED_WORKDIR="$LXC_ROOTFS" + ;; + *) + echo "Unknown media type $mediatype" >&2 + exit 1 + ;; +esac -OCI_CONF_FILE=$(getconfigpath "${DOWNLOAD_TEMP}" latest) LXC_CONF_FILE="${LXC_PATH}/config" entrypoint=$(getep "${OCI_CONF_FILE}") echo "lxc.execute.cmd = '${entrypoint}'" >> "${LXC_CONF_FILE}" echo "lxc.mount.auto = proc:mixed sys:mixed cgroup:mixed" >> "${LXC_CONF_FILE}" +case "$mediatype" in + application/vnd.*.image.layer.squashfs*) + echo "lxc.hook.version = 1" >> "${LXC_CONF_FILE}" + # shellcheck disable=SC2016 + echo "lxc.hook.pre-mount = $MOUNT_HELPER mount" \ + '${LXC_ROOTFS_PATH}/../oci:${LXC_NAME} ${LXC_ROOTFS_PATH}' \ + >> "${LXC_CONF_FILE}";; +esac + environment=$(getenv "${OCI_CONF_FILE}") # shellcheck disable=SC2039 while read -r line; do