Unverified Commit a1d5a1d4 by Stéphane Graber Committed by GitHub

Merge pull request #3301 from brauner/2020-03-17/fixes

lxc_user_nic: don't depend on MAP_FIXED
parents 9820e789 2120b89b
...@@ -399,6 +399,7 @@ lxc_user_nic_SOURCES = cmd/lxc_user_nic.c \ ...@@ -399,6 +399,7 @@ lxc_user_nic_SOURCES = cmd/lxc_user_nic.c \
network.c network.h \ network.c network.h \
parse.c parse.h \ parse.c parse.h \
raw_syscalls.c raw_syscalls.h \ raw_syscalls.c raw_syscalls.h \
file_utils.c file_utils.h \
string_utils.c string_utils.h \ string_utils.c string_utils.h \
syscall_wrappers.h syscall_wrappers.h
lxc_usernsexec_SOURCES = cmd/lxc_usernsexec.c \ lxc_usernsexec_SOURCES = cmd/lxc_usernsexec.c \
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#endif #endif
#include <alloca.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
...@@ -32,6 +31,7 @@ ...@@ -32,6 +31,7 @@
#include "compiler.h" #include "compiler.h"
#include "config.h" #include "config.h"
#include "file_utils.h"
#include "log.h" #include "log.h"
#include "memory_utils.h" #include "memory_utils.h"
#include "network.h" #include "network.h"
...@@ -77,7 +77,7 @@ static int open_and_lock(const char *path) ...@@ -77,7 +77,7 @@ static int open_and_lock(const char *path)
int ret; int ret;
struct flock lk; 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) { if (fd < 0) {
CMD_SYSERROR("Failed to open \"%s\"\n", path); CMD_SYSERROR("Failed to open \"%s\"\n", path);
return -1; return -1;
...@@ -592,40 +592,35 @@ struct entry_line { ...@@ -592,40 +592,35 @@ struct entry_line {
static bool cull_entries(int fd, char *name, char *net_type, char *net_link, static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
char *net_dev, bool *found_nicname) char *net_dev, bool *found_nicname)
{ {
__do_free char *buf = NULL;
__do_free struct entry_line *entry_lines = NULL; __do_free struct entry_line *entry_lines = NULL;
int i, ret;
char *buf, *buf_end, *buf_start;
struct stat sb;
int n = 0; int n = 0;
size_t length = 0;
int ret;
char *buf_end, *buf_start;
bool found, keep; bool found, keep;
ret = fstat(fd, &sb); ret = fd_to_buf(fd, &buf, &length);
if (ret < 0) { if (ret < 0) {
CMD_SYSERROR("Failed to fstat\n"); CMD_SYSERROR("Failed to read database file\n");
return false; return false;
} }
if (lseek(fd, 0, SEEK_SET) < 0)
if (!sb.st_size)
return false; return false;
buf = lxc_strmmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (length == 0)
if (buf == MAP_FAILED) {
CMD_SYSERROR("Failed to establish shared memory mapping\n");
return false; return false;
}
buf_start = buf; 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, while ((buf_start = find_line(buf_start, buf_end, name, net_type,
net_link, net_dev, &(bool){true}, &found, net_link, net_dev, &(bool){true}, &found,
&keep))) { &keep))) {
struct entry_line *newe; struct entry_line *newe;
newe = realloc(entry_lines, sizeof(*entry_lines) * (n + 1)); newe = realloc(entry_lines, sizeof(*entry_lines) * (n + 1));
if (!newe) { if (!newe)
lxc_strmunmap(buf, sb.st_size);
return false; return false;
}
if (found) if (found)
*found_nicname = true; *found_nicname = true;
...@@ -643,7 +638,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link, ...@@ -643,7 +638,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
buf_start = buf; buf_start = buf;
for (i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
if (!entry_lines[i].keep) if (!entry_lines[i].keep)
continue; continue;
...@@ -653,12 +648,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link, ...@@ -653,12 +648,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
buf_start++; buf_start++;
} }
ret = ftruncate(fd, buf_start - buf); return ftruncate(fd, buf_start - buf) == 0;
lxc_strmunmap(buf, sb.st_size);
if (ret < 0)
CMD_SYSERROR("Failed to set new file size\n");
return true;
} }
static int count_entries(char *buf, off_t len, char *name, char *net_type, char *net_link) 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 ...@@ -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, static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
char *intype, char *br, int allowed, char **cnic) 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; int ret;
size_t slen; size_t slen;
char *owner; char *owner;
char nicname[IFNAMSIZ]; char nicname[IFNAMSIZ];
struct stat sb;
struct alloted_s *n; struct alloted_s *n;
char *buf = NULL;
uid_t uid; uid_t uid;
for (n = names; n != NULL; n = n->next) 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, ...@@ -703,34 +692,27 @@ static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
owner = names->name; owner = names->name;
ret = fstat(fd, &sb); ret = fd_to_buf(fd, &buf, &length);
if (ret < 0) { if (ret < 0) {
CMD_SYSERROR("Failed to fstat\n"); CMD_SYSERROR("Failed to read database file\n");
return NULL; return false;
} }
if (lseek(fd, 0, SEEK_SET) < 0)
return false;
if (sb.st_size > 0) { if (length > 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;
}
owner = NULL; owner = NULL;
for (n = names; n != NULL; n = n->next) { for (n = names; n != NULL; n = n->next) {
int count; 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) if (count >= n->allowed)
continue; continue;
owner = n->name; owner = n->name;
break; break;
} }
lxc_strmunmap(buf, sb.st_size);
} }
if (!owner) if (!owner)
...@@ -787,30 +769,13 @@ static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid, ...@@ -787,30 +769,13 @@ static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
return NULL; return NULL;
} }
/* Note that the file needs to be truncated to the size **without** the if (lxc_pwrite_nointr(fd, newline, slen, length) != slen)
* \0 byte! Files are not \0-terminated! CMD_SYSERROR("Failed to append new entry \"%s\" to database file", newline);
*/
ret = ftruncate(fd, sb.st_size + slen); ret = ftruncate(fd, length + slen);
if (ret < 0) if (ret < 0)
CMD_SYSERROR("Failed to truncate file\n"); 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); return strdup(nicname);
} }
......
...@@ -133,6 +133,17 @@ ssize_t lxc_write_nointr(int fd, const void *buf, size_t count) ...@@ -133,6 +133,17 @@ ssize_t lxc_write_nointr(int fd, const void *buf, size_t count)
return ret; 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 lxc_send_nointr(int sockfd, void *buf, size_t len, int flags)
{ {
ssize_t ret; ssize_t ret;
...@@ -400,37 +411,39 @@ int fd_to_fd(int from, int to) ...@@ -400,37 +411,39 @@ int fd_to_fd(int from, int to)
return 0; 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; __do_free char *copy = NULL;
if (!length) if (!length)
return NULL; return 0;
*length = 0; *length = 0;
for (;;) { for (;;) {
ssize_t bytes_read; ssize_t bytes_read;
char buf[4096]; char chunk[4096];
char *old = copy; 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) if (bytes_read < 0)
return NULL; return 0;
if (!bytes_read) if (!bytes_read)
break; break;
copy = must_realloc(old, (*length + bytes_read) * sizeof(*old)); copy = must_realloc(old, (*length + bytes_read) * sizeof(*old));
memcpy(copy + *length, buf, bytes_read); memcpy(copy + *length, chunk, bytes_read);
*length += 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) char *file_to_buf(const char *path, size_t *length)
{ {
__do_close int fd = -EBADF; __do_close int fd = -EBADF;
char *buf = NULL;
if (!length) if (!length)
return NULL; return NULL;
...@@ -439,7 +452,10 @@ char *file_to_buf(const char *path, size_t *length) ...@@ -439,7 +452,10 @@ char *file_to_buf(const char *path, size_t *length)
if (fd < 0) if (fd < 0)
return NULL; 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) 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) ...@@ -470,8 +486,7 @@ FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer)
__do_free char *buf = NULL; __do_free char *buf = NULL;
size_t len = 0; size_t len = 0;
buf = fd_to_buf(fd, &len); if (fd_to_buf(fd, &buf, &len) < 0)
if (!buf)
return NULL; return NULL;
f = fmemopen(buf, len, mode); f = fmemopen(buf, len, mode);
......
...@@ -24,6 +24,8 @@ extern int lxc_read_from_file(const char *filename, void *buf, size_t count); ...@@ -24,6 +24,8 @@ extern int lxc_read_from_file(const char *filename, void *buf, size_t count);
/* send and receive buffers completely */ /* send and receive buffers completely */
extern ssize_t lxc_write_nointr(int fd, const void *buf, size_t count); 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_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(int fd, void *buf, size_t count);
extern ssize_t lxc_read_nointr_expect(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); ...@@ -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, extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset,
size_t count); size_t count);
extern char *file_to_buf(const char *path, size_t *length); 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 fd_to_fd(int from, int to);
extern int lxc_open_dirfd(const char *dir); extern int lxc_open_dirfd(const char *dir);
extern FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer); extern FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment