From 7efe838822dbd48429863a625a576960ff85fe6a Mon Sep 17 00:00:00 2001 From: "Andrew J. Hesford" Date: Tue, 22 Dec 2020 09:44:58 -0500 Subject: [PATCH] lxc: fix config parsing with linux5.10 --- srcpkgs/lxc/patches/fix-config-parsing.patch | 169 +++++++++++++++++++ srcpkgs/lxc/template | 2 +- 2 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 srcpkgs/lxc/patches/fix-config-parsing.patch diff --git a/srcpkgs/lxc/patches/fix-config-parsing.patch b/srcpkgs/lxc/patches/fix-config-parsing.patch new file mode 100644 index 00000000000..cbb435c3e4a --- /dev/null +++ b/srcpkgs/lxc/patches/fix-config-parsing.patch @@ -0,0 +1,169 @@ +From 26dffd825842edf019bc17da24a6809ed51c048c Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Mon, 16 Nov 2020 12:18:14 +0100 +Subject: [PATCH] parse: rework config parsing routine + +Signed-off-by: Christian Brauner +--- + src/lxc/file_utils.c | 7 +++++-- + src/lxc/file_utils.h | 6 +++++- + src/lxc/parse.c | 49 ++++++++++++++++++++++++-------------------- + 3 files changed, 37 insertions(+), 25 deletions(-) + +diff --git src/lxc/file_utils.c src/lxc/file_utils.c +index fafaba354c..3b4bffb399 100644 +--- src/lxc/file_utils.c ++++ src/lxc/file_utils.c +@@ -382,8 +382,10 @@ ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset, size_t count) + return ret; + } + +-int fd_to_fd(int from, int to) ++ssize_t __fd_to_fd(int from, int to) + { ++ ssize_t total_bytes = 0; ++ + for (;;) { + uint8_t buf[PATH_MAX]; + uint8_t *p = buf; +@@ -407,9 +409,10 @@ int fd_to_fd(int from, int to) + bytes_to_write -= bytes_written; + p += bytes_written; + } while (bytes_to_write > 0); ++ total_bytes += bytes_to_write; + } + +- return 0; ++ return total_bytes; + } + + int fd_to_buf(int fd, char **buf, size_t *length) +diff --git src/lxc/file_utils.h src/lxc/file_utils.h +index ea9570dd18..11acdb3a7b 100644 +--- src/lxc/file_utils.h ++++ src/lxc/file_utils.h +@@ -68,7 +68,11 @@ __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); + __hidden extern int fd_to_buf(int fd, char **buf, size_t *length); +-__hidden extern int fd_to_fd(int from, int to); ++__hidden extern ssize_t __fd_to_fd(int from, int to); ++static inline int fd_to_fd(int from, int to) ++{ ++ return __fd_to_fd(from, to) >= 0; ++} + __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 *fopen_cached(const char *path, const char *mode, void **caller_freed_buffer); +diff --git src/lxc/parse.c src/lxc/parse.c +index 291bf3efc1..5a5b853458 100644 +--- src/lxc/parse.c ++++ src/lxc/parse.c +@@ -5,6 +5,7 @@ + #endif + #include + #include ++#include + #include + #include + #include +@@ -50,11 +51,12 @@ int lxc_strmunmap(void *addr, size_t length) + + int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback, void *data) + { +- int saved_errno; +- ssize_t ret = -1, bytes_sent; +- char *line; +- int fd = -1, memfd = -1; ++ __do_close int fd = -EBADF, memfd = -EBADF; ++ ssize_t ret = -1; + char *buf = NULL; ++ struct stat st = {}; ++ ssize_t bytes; ++ char *line; + + memfd = memfd_create(".lxc_config_file", MFD_CLOEXEC); + if (memfd < 0) { +@@ -65,8 +67,7 @@ int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback, void *da + goto on_error; + } + +- TRACE("Failed to create in-memory file. Falling back to " +- "temporary file"); ++ TRACE("Failed to create in-memory file. Falling back to temporary file"); + memfd = lxc_make_tmpfile(template, true); + if (memfd < 0) { + SYSERROR("Failed to create temporary file \"%s\"", template); +@@ -80,10 +81,21 @@ int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback, void *da + goto on_error; + } + +- /* sendfile() handles up to 2GB. No config file should be that big. */ +- bytes_sent = lxc_sendfile_nointr(memfd, fd, NULL, LXC_SENDFILE_MAX); +- if (bytes_sent < 0) { +- SYSERROR("Failed to sendfile \"%s\"", file); ++ ret = fstat(fd, &st); ++ if (ret) { ++ SYSERROR("Failed to stat file \"%s\"", file); ++ goto on_error; ++ } ++ ++ if (st.st_size > INT_MAX) { ++ SYSERROR("Excessively large config file \"%s\"", file); ++ goto on_error; ++ } ++ ++ ++ bytes = __fd_to_fd(fd, memfd); ++ if (bytes < 0) { ++ SYSERROR("Failed to copy config file \"%s\"", file); + goto on_error; + } + +@@ -92,7 +104,7 @@ int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback, void *da + SYSERROR("Failed to append zero byte"); + goto on_error; + } +- bytes_sent++; ++ bytes++; + + ret = lseek(memfd, 0, SEEK_SET); + if (ret < 0) { +@@ -101,8 +113,7 @@ int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback, void *da + } + + ret = -1; +- buf = mmap(NULL, bytes_sent, PROT_READ | PROT_WRITE, +- MAP_SHARED | MAP_POPULATE, memfd, 0); ++ buf = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_POPULATE, memfd, 0); + if (buf == MAP_FAILED) { + buf = NULL; + SYSERROR("Failed to mmap"); +@@ -117,24 +128,18 @@ int lxc_file_for_each_line_mmap(const char *file, lxc_file_cb callback, void *da + * error. + */ + if (ret < 0) +- ERROR("Failed to parse config file \"%s\" at " +- "line \"%s\"", file, line); ++ ERROR("Failed to parse config file \"%s\" at line \"%s\"", ++ file, line); + break; + } + } + + on_error: +- saved_errno = errno; +- if (fd >= 0) +- close(fd); +- if (memfd >= 0) +- close(memfd); +- if (buf && munmap(buf, bytes_sent)) { ++ if (buf && munmap(buf, bytes)) { + SYSERROR("Failed to unmap"); + if (ret == 0) + ret = -1; + } +- errno = saved_errno; + + return ret; + } diff --git a/srcpkgs/lxc/template b/srcpkgs/lxc/template index 128024dc038..03fbeb400f5 100644 --- a/srcpkgs/lxc/template +++ b/srcpkgs/lxc/template @@ -3,7 +3,7 @@ _desc="Linux Containers" pkgname=lxc version=4.0.5 -revision=2 +revision=3 build_style=gnu-configure configure_args="--enable-doc --enable-seccomp --enable-capabilities --enable-apparmor --with-distro=none