]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc_user_nic: don't depend on MAP_FIXED 3301/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 17 Mar 2020 13:55:45 +0000 (14:55 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 17 Mar 2020 16:26:14 +0000 (17:26 +0100)
as this breaks on sparc.

Closes #3262.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/Makefile.am
src/lxc/cmd/lxc_user_nic.c
src/lxc/file_utils.c
src/lxc/file_utils.h

index e486f91b30824a498beafbd9b866b37bbf0aef12..2f850135a791b6a201a44d51fe61cf53932e2598 100644 (file)
@@ -399,6 +399,7 @@ lxc_user_nic_SOURCES = cmd/lxc_user_nic.c \
                       network.c network.h \
                       parse.c parse.h \
                       raw_syscalls.c raw_syscalls.h \
+                      file_utils.c file_utils.h \
                       string_utils.c string_utils.h \
                       syscall_wrappers.h
 lxc_usernsexec_SOURCES = cmd/lxc_usernsexec.c \
index 7a2e47011b7ea07ddd68765af81a61ef64099822..47048456d22808183e83f186fd90667540a6c290 100644 (file)
@@ -3,7 +3,6 @@
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE 1
 #endif
-#include <alloca.h>
 #include <arpa/inet.h>
 #include <ctype.h>
 #include <errno.h>
@@ -32,6 +31,7 @@
 
 #include "compiler.h"
 #include "config.h"
+#include "file_utils.h"
 #include "log.h"
 #include "memory_utils.h"
 #include "network.h"
@@ -77,7 +77,7 @@ static int open_and_lock(const char *path)
        int ret;
        struct flock lk;
 
-       fd = open(path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);
+       fd = open(path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | O_CLOEXEC);
        if (fd < 0) {
                CMD_SYSERROR("Failed to open \"%s\"\n", path);
                return -1;
@@ -592,40 +592,35 @@ struct entry_line {
 static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
                         char *net_dev, bool *found_nicname)
 {
+       __do_free char *buf = NULL;
        __do_free struct entry_line *entry_lines = NULL;
-       int i, ret;
-       char *buf, *buf_end, *buf_start;
-       struct stat sb;
        int n = 0;
+       size_t length = 0;
+       int ret;
+       char *buf_end, *buf_start;
        bool found, keep;
 
-       ret = fstat(fd, &sb);
+       ret = fd_to_buf(fd, &buf, &length);
        if (ret < 0) {
-               CMD_SYSERROR("Failed to fstat\n");
+               CMD_SYSERROR("Failed to read database file\n");
                return false;
        }
-
-       if (!sb.st_size)
+       if (lseek(fd, 0, SEEK_SET) < 0)
                return false;
 
-       buf = lxc_strmmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-       if (buf == MAP_FAILED) {
-               CMD_SYSERROR("Failed to establish shared memory mapping\n");
+       if (length == 0)
                return false;
-       }
 
        buf_start = buf;
-       buf_end = buf + sb.st_size;
+       buf_end = buf + length;
        while ((buf_start = find_line(buf_start, buf_end, name, net_type,
                                      net_link, net_dev, &(bool){true}, &found,
                                      &keep))) {
                struct entry_line *newe;
 
                newe = realloc(entry_lines, sizeof(*entry_lines) * (n + 1));
-               if (!newe) {
-                       lxc_strmunmap(buf, sb.st_size);
+               if (!newe)
                        return false;
-               }
 
                if (found)
                        *found_nicname = true;
@@ -643,7 +638,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
 
        buf_start = buf;
 
-       for (i = 0; i < n; i++) {
+       for (int i = 0; i < n; i++) {
                if (!entry_lines[i].keep)
                        continue;
 
@@ -653,12 +648,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
                buf_start++;
        }
 
-       ret = ftruncate(fd, buf_start - buf);
-       lxc_strmunmap(buf, sb.st_size);
-       if (ret < 0)
-               CMD_SYSERROR("Failed to set new file size\n");
-
-       return true;
+       return ftruncate(fd, buf_start - buf) == 0;
 }
 
 static int count_entries(char *buf, off_t len, char *name, char *net_type, char *net_link)
@@ -685,14 +675,13 @@ static int count_entries(char *buf, off_t len, char *name, char *net_type, char
 static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
                              char *intype, char *br, int allowed, char **cnic)
 {
-       __do_free char *newline = NULL;
+       __do_free char *buf = NULL, *newline = NULL;
+       size_t length = 0;
        int ret;
        size_t slen;
        char *owner;
        char nicname[IFNAMSIZ];
-       struct stat sb;
        struct alloted_s *n;
-       char *buf = NULL;
        uid_t uid;
 
        for (n = names; n != NULL; n = n->next)
@@ -703,34 +692,27 @@ static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
 
        owner = names->name;
 
-       ret = fstat(fd, &sb);
+       ret = fd_to_buf(fd, &buf, &length);
        if (ret < 0) {
-               CMD_SYSERROR("Failed to fstat\n");
-               return NULL;
+               CMD_SYSERROR("Failed to read database file\n");
+               return false;
        }
+       if (lseek(fd, 0, SEEK_SET) < 0)
+               return false;
 
-       if (sb.st_size > 0) {
-               buf = lxc_strmmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
-                                 MAP_SHARED, fd, 0);
-               if (buf == MAP_FAILED) {
-                       CMD_SYSERROR("Failed to establish shared memory mapping\n");
-                       return NULL;
-               }
-
+       if (length > 0) {
                owner = NULL;
 
                for (n = names; n != NULL; n = n->next) {
                        int count;
 
-                       count = count_entries(buf, sb.st_size, n->name, intype, br);
+                       count = count_entries(buf, length, n->name, intype, br);
                        if (count >= n->allowed)
                                continue;
 
                        owner = n->name;
                        break;
                }
-
-               lxc_strmunmap(buf, sb.st_size);
        }
 
        if (!owner)
@@ -787,30 +769,13 @@ static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
                return NULL;
        }
 
-       /* Note that the file needs to be truncated to the size **without** the
-        * \0 byte! Files are not \0-terminated!
-        */
-       ret = ftruncate(fd, sb.st_size + slen);
+       if (lxc_pwrite_nointr(fd, newline, slen, length) != slen)
+               CMD_SYSERROR("Failed to append new entry \"%s\" to database file", newline);
+
+       ret = ftruncate(fd, length + slen);
        if (ret < 0)
                CMD_SYSERROR("Failed to truncate file\n");
 
-       buf = lxc_strmmap(NULL, sb.st_size + slen, PROT_READ | PROT_WRITE,
-                         MAP_SHARED, fd, 0);
-       if (buf == MAP_FAILED) {
-               CMD_SYSERROR("Failed to establish shared memory mapping\n");
-
-               if (lxc_netdev_delete_by_name(nicname) != 0)
-                       usernic_error("Error unlinking %s\n", nicname);
-
-               return NULL;
-       }
-
-       /* Note that the memory needs to be moved in the buffer **without** the
-        * \0 byte! Files are not \0-terminated!
-        */
-       memmove(buf + sb.st_size, newline, slen);
-       lxc_strmunmap(buf, sb.st_size + slen);
-
        return strdup(nicname);
 }
 
index ab445751bda9682847d1d5075fdcb9d8c8e58d93..1689cbaa7f90d360b39216a51bcc777947da2f60 100644 (file)
@@ -133,6 +133,17 @@ ssize_t lxc_write_nointr(int fd, const void *buf, size_t count)
        return ret;
 }
 
+ssize_t lxc_pwrite_nointr(int fd, const void *buf, size_t count, off_t offset)
+{
+       ssize_t ret;
+
+       do {
+               ret = pwrite(fd, buf, count, offset);
+       } while (ret < 0 && errno == EINTR);
+
+       return ret;
+}
+
 ssize_t lxc_send_nointr(int sockfd, void *buf, size_t len, int flags)
 {
        ssize_t ret;
@@ -400,37 +411,39 @@ int fd_to_fd(int from, int to)
        return 0;
 }
 
-static char *fd_to_buf(int fd, size_t *length)
+int fd_to_buf(int fd, char **buf, size_t *length)
 {
        __do_free char *copy = NULL;
 
        if (!length)
-               return NULL;
+               return 0;
 
        *length = 0;
        for (;;) {
                ssize_t bytes_read;
-               char buf[4096];
+               char chunk[4096];
                char *old = copy;
 
-               bytes_read = lxc_read_nointr(fd, buf, sizeof(buf));
+               bytes_read = lxc_read_nointr(fd, chunk, sizeof(chunk));
                if (bytes_read < 0)
-                       return NULL;
+                       return 0;
 
                if (!bytes_read)
                        break;
 
                copy = must_realloc(old, (*length + bytes_read) * sizeof(*old));
-               memcpy(copy + *length, buf, bytes_read);
+               memcpy(copy + *length, chunk, bytes_read);
                *length += bytes_read;
        }
 
-       return move_ptr(copy);
+       *buf = move_ptr(copy);
+       return 0;
 }
 
 char *file_to_buf(const char *path, size_t *length)
 {
        __do_close int fd = -EBADF;
+       char *buf = NULL;
 
        if (!length)
                return NULL;
@@ -439,7 +452,10 @@ char *file_to_buf(const char *path, size_t *length)
        if (fd < 0)
                return NULL;
 
-       return fd_to_buf(fd, length);
+       if (fd_to_buf(fd, &buf, length) < 0)
+               return NULL;
+
+       return buf;
 }
 
 FILE *fopen_cached(const char *path, const char *mode, void **caller_freed_buffer)
@@ -470,8 +486,7 @@ FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer)
        __do_free char *buf = NULL;
        size_t len = 0;
 
-       buf = fd_to_buf(fd, &len);
-       if (!buf)
+       if (fd_to_buf(fd, &buf, &len) < 0)
                return NULL;
 
        f = fmemopen(buf, len, mode);
index 8b31b976e6e3132fc987fde782107faab5c85550..6d5dbf68d66b2124948da7f5337a4091678cb42c 100644 (file)
@@ -24,6 +24,8 @@ extern int lxc_read_from_file(const char *filename, void *buf, size_t count);
 
 /* send and receive buffers completely */
 extern ssize_t lxc_write_nointr(int fd, const void *buf, size_t count);
+extern ssize_t lxc_pwrite_nointr(int fd, const void *buf, size_t count,
+                                off_t offset);
 extern ssize_t lxc_send_nointr(int sockfd, void *buf, size_t len, int flags);
 extern ssize_t lxc_read_nointr(int fd, void *buf, size_t count);
 extern ssize_t lxc_read_nointr_expect(int fd, void *buf, size_t count,
@@ -49,6 +51,7 @@ extern FILE *fopen_cloexec(const char *path, const char *mode);
 extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset,
                                   size_t count);
 extern char *file_to_buf(const char *path, size_t *length);
+extern int fd_to_buf(int fd, char **buf, size_t *length);
 extern int fd_to_fd(int from, int to);
 extern int lxc_open_dirfd(const char *dir);
 extern FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer);