Unverified Commit 3aa3407f by Stéphane Graber Committed by GitHub

Merge pull request #3595 from brauner/2020-12-08/fixes

tree-wide: fixes
parents 0c9621be c3e48967
...@@ -2749,9 +2749,6 @@ static int device_cgroup_rule_parse_devpath(struct device_item *device, ...@@ -2749,9 +2749,6 @@ static int device_cgroup_rule_parse_devpath(struct device_item *device,
if (device_cgroup_parse_access(device, mode) < 0) if (device_cgroup_parse_access(device, mode) < 0)
return -1; return -1;
if (n_parts == 1)
return ret_set_errno(-1, EINVAL);
ret = stat(path, &sb); ret = stat(path, &sb);
if (ret < 0) if (ret < 0)
return ret_set_errno(-1, errno); return ret_set_errno(-1, errno);
......
...@@ -479,7 +479,7 @@ int main(int argc, char *argv[]) ...@@ -479,7 +479,7 @@ int main(int argc, char *argv[])
break; break;
} }
default: default:
ret = kill(pid, was_interrupted); kill(pid, was_interrupted);
break; break;
} }
ret = EXIT_SUCCESS; ret = EXIT_SUCCESS;
......
...@@ -1201,7 +1201,9 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs) ...@@ -1201,7 +1201,9 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs)
} }
/* Fallback to bind-mounting the device from the host. */ /* Fallback to bind-mounting the device from the host. */
snprintf(hostpath, sizeof(hostpath), "/dev/%s", device->name); ret = snprintf(hostpath, sizeof(hostpath), "/dev/%s", device->name);
if (ret < 0 || (size_t)ret >= sizeof(hostpath))
return ret_errno(EIO);
ret = safe_mount_beneath_at(dev_dir_fd, hostpath, device->name, NULL, MS_BIND, NULL); ret = safe_mount_beneath_at(dev_dir_fd, hostpath, device->name, NULL, MS_BIND, NULL);
if (ret < 0) { if (ret < 0) {
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "config.h" #include "config.h"
#include "list.h" #include "list.h"
#include "lxcseccomp.h" #include "lxcseccomp.h"
#include "memory_utils.h"
#include "ringbuf.h" #include "ringbuf.h"
#include "start.h" #include "start.h"
#include "terminal.h" #include "terminal.h"
...@@ -69,6 +70,16 @@ struct lxc_cgroup { ...@@ -69,6 +70,16 @@ struct lxc_cgroup {
}; };
}; };
static void free_lxc_cgroup(struct lxc_cgroup *ptr)
{
if (ptr) {
free(ptr->subsystem);
free(ptr->value);
free_disarm(ptr);
}
}
define_cleanup_function(struct lxc_cgroup *, free_lxc_cgroup);
#if !HAVE_SYS_RESOURCE_H #if !HAVE_SYS_RESOURCE_H
#define RLIM_INFINITY ((unsigned long)-1) #define RLIM_INFINITY ((unsigned long)-1)
struct rlimit { struct rlimit {
...@@ -87,6 +98,15 @@ struct lxc_limit { ...@@ -87,6 +98,15 @@ struct lxc_limit {
struct rlimit limit; struct rlimit limit;
}; };
static void free_lxc_limit(struct lxc_limit *ptr)
{
if (ptr) {
free(ptr->resource);
free_disarm(ptr);
}
}
define_cleanup_function(struct lxc_limit *, free_lxc_limit);
enum idtype { enum idtype {
ID_TYPE_UID, ID_TYPE_UID,
ID_TYPE_GID ID_TYPE_GID
...@@ -102,6 +122,16 @@ struct lxc_sysctl { ...@@ -102,6 +122,16 @@ struct lxc_sysctl {
char *value; char *value;
}; };
static void free_lxc_sysctl(struct lxc_sysctl *ptr)
{
if (ptr) {
free(ptr->key);
free(ptr->value);
free_disarm(ptr);
}
}
define_cleanup_function(struct lxc_sysctl *, free_lxc_sysctl);
/* /*
* Defines a structure to configure proc filesystem at runtime. * Defines a structure to configure proc filesystem at runtime.
* @filename : the proc filesystem will be configured without the "lxc.proc" prefix * @filename : the proc filesystem will be configured without the "lxc.proc" prefix
...@@ -112,6 +142,16 @@ struct lxc_proc { ...@@ -112,6 +142,16 @@ struct lxc_proc {
char *value; char *value;
}; };
static void free_lxc_proc(struct lxc_proc *ptr)
{
if (ptr) {
free(ptr->filename);
free(ptr->value);
free_disarm(ptr);
}
}
define_cleanup_function(struct lxc_proc *, free_lxc_proc);
/* /*
* id_map is an id map entry. Form in confile is: * id_map is an id map entry. Form in confile is:
* lxc.idmap = u 0 9800 100 * lxc.idmap = u 0 9800 100
......
...@@ -9,24 +9,22 @@ ...@@ -9,24 +9,22 @@
#include "conf.h" #include "conf.h"
#include "confile_utils.h" #include "confile_utils.h"
#define strprint(str, inlen, ...) \ #define strprint(str, inlen, ...) \
do { \ do { \
if (str) \ if (str) \
len = snprintf(str, inlen, ##__VA_ARGS__); \ len = snprintf(str, inlen, ##__VA_ARGS__); \
else \ else \
len = snprintf((char *){""}, 0, ##__VA_ARGS__); \ len = snprintf((char *){""}, 0, ##__VA_ARGS__); \
if (len < 0) { \ if (len < 0) \
SYSERROR("failed to create string"); \ return log_error_errno(-EIO, EIO, "failed to create string"); \
return -1; \ fulllen += len; \
}; \ if (inlen > 0) { \
fulllen += len; \ if (str) \
if (inlen > 0) { \ str += len; \
if (str) \ inlen -= len; \
str += len; \ if (inlen < 0) \
inlen -= len; \ inlen = 0; \
if (inlen < 0) \ } \
inlen = 0; \
} \
} while (0); } while (0);
__hidden extern int parse_idmaps(const char *idmap, char *type, unsigned long *nsid, __hidden extern int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
......
...@@ -79,36 +79,26 @@ struct criu_opts { ...@@ -79,36 +79,26 @@ struct criu_opts {
static int load_tty_major_minor(char *directory, char *output, int len) static int load_tty_major_minor(char *directory, char *output, int len)
{ {
FILE *f;
char path[PATH_MAX]; char path[PATH_MAX];
int ret; ssize_t ret;
ret = snprintf(path, sizeof(path), "%s/tty.info", directory); ret = snprintf(path, sizeof(path), "%s/tty.info", directory);
if (ret < 0 || ret >= sizeof(path)) { if (ret < 0 || (size_t)ret >= sizeof(path))
ERROR("snprintf'd too many characters: %d", ret); return ret_errno(EIO);
return -1;
}
f = fopen(path, "re"); ret = lxc_read_from_file(path, output, len);
if (!f) { if (ret < 0) {
/* This means we're coming from a liblxc which didn't export /*
* This means we're coming from a liblxc which didn't export
* the tty info. In this case they had to have lxc.console.path * the tty info. In this case they had to have lxc.console.path
* = * none, so there's no problem restoring. * = * none, so there's no problem restoring.
*/ */
if (errno == ENOENT) if (errno == ENOENT)
return 0; return 0;
SYSERROR("couldn't open %s", path); return log_error_errno(-errno, errno, "Failed to open \"%s\"", path);
return -1;
} }
if (!fgets(output, len, f)) {
fclose(f);
SYSERROR("couldn't read %s", path);
return -1;
}
fclose(f);
return 0; return 0;
} }
......
...@@ -13,6 +13,7 @@ extern "C" { ...@@ -13,6 +13,7 @@ extern "C" {
#include <sys/types.h> #include <sys/types.h>
#include "compiler.h" #include "compiler.h"
#include "memory_utils.h"
#include "state.h" #include "state.h"
struct lxc_msg; struct lxc_msg;
...@@ -94,6 +95,13 @@ extern int lxc_container_get(struct lxc_container *c); ...@@ -94,6 +95,13 @@ extern int lxc_container_get(struct lxc_container *c);
* If it is the last reference, free the lxccontainer and return 1. * If it is the last reference, free the lxccontainer and return 1.
*/ */
extern int lxc_container_put(struct lxc_container *c); extern int lxc_container_put(struct lxc_container *c);
static inline void put_lxc_container(struct lxc_container *c)
{
if (c)
lxc_container_put(c);
}
define_cleanup_function(struct lxc_container *, put_lxc_container);
#define __put_lxc_container call_cleaner(put_lxc_container)
/* /*
* Get a list of valid wait states. * Get a list of valid wait states.
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
#include "lxclock.h" #include "lxclock.h"
#include "memory_utils.h"
#include "utils.h" #include "utils.h"
#ifdef MUTEX_DEBUGGING #ifdef MUTEX_DEBUGGING
...@@ -35,7 +36,6 @@ static inline void dump_stacktrace(void) ...@@ -35,7 +36,6 @@ static inline void dump_stacktrace(void)
void *array[MAX_STACKDEPTH]; void *array[MAX_STACKDEPTH];
size_t size; size_t size;
char **strings; char **strings;
size_t i;
size = backtrace(array, MAX_STACKDEPTH); size = backtrace(array, MAX_STACKDEPTH);
strings = backtrace_symbols(array, size); strings = backtrace_symbols(array, size);
...@@ -43,7 +43,7 @@ static inline void dump_stacktrace(void) ...@@ -43,7 +43,7 @@ static inline void dump_stacktrace(void)
/* Using fprintf here as our logging module is not thread safe. */ /* Using fprintf here as our logging module is not thread safe. */
fprintf(stderr, "\tObtained %zu stack frames\n", size); fprintf(stderr, "\tObtained %zu stack frames\n", size);
for (i = 0; i < size; i++) for (int i = 0; i < size; i++)
fprintf(stderr, "\t\t%s\n", strings[i]); fprintf(stderr, "\t\t%s\n", strings[i]);
free(strings); free(strings);
...@@ -80,9 +80,9 @@ static void unlock_mutex(pthread_mutex_t *l) ...@@ -80,9 +80,9 @@ static void unlock_mutex(pthread_mutex_t *l)
static char *lxclock_name(const char *p, const char *n) static char *lxclock_name(const char *p, const char *n)
{ {
__do_free char *dest = NULL, *rundir = NULL;
int ret; int ret;
size_t len; size_t len;
char *dest, *rundir;
/* lockfile will be: /* lockfile will be:
* "/run" + "/lxc/lock/$lxcpath/$lxcname + '\0' if root * "/run" + "/lxc/lock/$lxcpath/$lxcname + '\0' if root
...@@ -100,134 +100,96 @@ static char *lxclock_name(const char *p, const char *n) ...@@ -100,134 +100,96 @@ static char *lxclock_name(const char *p, const char *n)
len += strlen(rundir); len += strlen(rundir);
dest = malloc(len); dest = malloc(len);
if (!dest) { if (!dest)
free(rundir);
return NULL; return NULL;
}
ret = snprintf(dest, len, "%s/lxc/lock/%s", rundir, p); ret = snprintf(dest, len, "%s/lxc/lock/%s", rundir, p);
if (ret < 0 || (size_t)ret >= len) { if (ret < 0 || (size_t)ret >= len)
free(dest); return ret_set_errno(NULL, EIO);
free(rundir);
return NULL;
}
ret = mkdir_p(dest, 0755); ret = mkdir_p(dest, 0755);
if (ret < 0) { if (ret < 0)
free(dest);
free(rundir);
return NULL; return NULL;
}
ret = snprintf(dest, len, "%s/lxc/lock/%s/.%s", rundir, p, n); ret = snprintf(dest, len, "%s/lxc/lock/%s/.%s", rundir, p, n);
free(rundir); if (ret < 0 || (size_t)ret >= len)
if (ret < 0 || (size_t)ret >= len) { return ret_set_errno(NULL, EIO);
free(dest);
return NULL;
}
return dest; return move_ptr(dest);
} }
static sem_t *lxc_new_unnamed_sem(void) static sem_t *lxc_new_unnamed_sem(void)
{ {
__do_free sem_t *s = NULL;
int ret; int ret;
sem_t *s;
s = malloc(sizeof(*s)); s = malloc(sizeof(*s));
if (!s) if (!s)
return NULL; return ret_set_errno(NULL, ENOMEM);
ret = sem_init(s, 0, 1); ret = sem_init(s, 0, 1);
if (ret < 0) { if (ret < 0)
free(s);
return NULL; return NULL;
}
return s; return move_ptr(s);
} }
struct lxc_lock *lxc_newlock(const char *lxcpath, const char *name) struct lxc_lock *lxc_newlock(const char *lxcpath, const char *name)
{ {
struct lxc_lock *l; __do_free struct lxc_lock *l = NULL;
l = malloc(sizeof(*l)); l = zalloc(sizeof(*l));
if (!l) if (!l)
goto on_error; return ret_set_errno(NULL, ENOMEM);
if (!name) { if (name) {
l->type = LXC_LOCK_FLOCK;
l->u.f.fname = lxclock_name(lxcpath, name);
if (!l->u.f.fname)
return ret_set_errno(NULL, ENOMEM);
l->u.f.fd = -EBADF;
} else {
l->type = LXC_LOCK_ANON_SEM; l->type = LXC_LOCK_ANON_SEM;
l->u.sem = lxc_new_unnamed_sem(); l->u.sem = lxc_new_unnamed_sem();
if (!l->u.sem) { if (!l->u.sem)
free(l); return ret_set_errno(NULL, ENOMEM);
l = NULL;
}
goto on_error;
} }
l->type = LXC_LOCK_FLOCK; return move_ptr(l);
l->u.f.fname = lxclock_name(lxcpath, name);
if (!l->u.f.fname) {
if (!name)
free(l->u.sem);
free(l);
l = NULL;
goto on_error;
}
l->u.f.fd = -1;
on_error:
return l;
} }
int lxclock(struct lxc_lock *l, int timeout) int lxclock(struct lxc_lock *l, int timeout)
{ {
int ret = -1;
struct flock lk; struct flock lk;
int ret = -1, saved_errno = errno;
switch(l->type) { switch (l->type) {
case LXC_LOCK_ANON_SEM: case LXC_LOCK_ANON_SEM:
if (!timeout) { if (!timeout) {
ret = sem_wait(l->u.sem); ret = sem_wait(l->u.sem);
if (ret < 0)
saved_errno = errno;
} else { } else {
struct timespec ts; struct timespec ts;
ret = clock_gettime(CLOCK_REALTIME, &ts); ret = clock_gettime(CLOCK_REALTIME, &ts);
if (ret < 0) { if (ret < 0)
ret = -2; return -2;
goto on_error;
}
ts.tv_sec += timeout; ts.tv_sec += timeout;
ret = sem_timedwait(l->u.sem, &ts); ret = sem_timedwait(l->u.sem, &ts);
if (ret < 0)
saved_errno = errno;
} }
break; break;
case LXC_LOCK_FLOCK: case LXC_LOCK_FLOCK:
ret = -2; if (timeout)
if (timeout) { return log_error(-2, "Timeouts are not supported with file locks");
ERROR("Timeouts are not supported with file locks");
goto on_error;
}
if (!l->u.f.fname) { if (!l->u.f.fname)
ERROR("No filename set for file lock"); return log_error(-2, "No filename set for file lock");
goto on_error;
}
if (l->u.f.fd == -1) { if (l->u.f.fd < 0) {
l->u.f.fd = open(l->u.f.fname, O_CREAT | O_RDWR | O_NOFOLLOW | O_CLOEXEC | O_NOCTTY, S_IWUSR | S_IRUSR); l->u.f.fd = open(l->u.f.fname, O_CREAT | O_RDWR | O_NOFOLLOW | O_CLOEXEC | O_NOCTTY, S_IWUSR | S_IRUSR);
if (l->u.f.fd == -1) { if (l->u.f.fd < 0)
SYSERROR("Failed to open \"%s\"", l->u.f.fname); return log_error_errno(-2, errno, "Failed to open \"%s\"", l->u.f.fname);
saved_errno = errno;
goto on_error;
}
} }
memset(&lk, 0, sizeof(struct flock)); memset(&lk, 0, sizeof(struct flock));
...@@ -236,59 +198,47 @@ int lxclock(struct lxc_lock *l, int timeout) ...@@ -236,59 +198,47 @@ int lxclock(struct lxc_lock *l, int timeout)
lk.l_whence = SEEK_SET; lk.l_whence = SEEK_SET;
ret = fcntl(l->u.f.fd, F_OFD_SETLKW, &lk); ret = fcntl(l->u.f.fd, F_OFD_SETLKW, &lk);
if (ret < 0) { if (ret < 0 && errno == EINVAL)
if (errno == EINVAL) ret = flock(l->u.f.fd, LOCK_EX);
ret = flock(l->u.f.fd, LOCK_EX);
saved_errno = errno;
}
break; break;
default:
return ret_set_errno(-1, EINVAL);
} }
on_error:
errno = saved_errno;
return ret; return ret;
} }
int lxcunlock(struct lxc_lock *l) int lxcunlock(struct lxc_lock *l)
{ {
struct flock lk; struct flock lk;
int ret = 0, saved_errno = errno; int ret = 0;
switch (l->type) { switch (l->type) {
case LXC_LOCK_ANON_SEM: case LXC_LOCK_ANON_SEM:
if (!l->u.sem) { if (!l->u.sem)
ret = -2; return -2;
} else {
ret = sem_post(l->u.sem);
saved_errno = errno;
}
ret = sem_post(l->u.sem);
break; break;
case LXC_LOCK_FLOCK: case LXC_LOCK_FLOCK:
if (l->u.f.fd != -1) { if (l->u.f.fd < 0)
memset(&lk, 0, sizeof(struct flock)); return -2;
lk.l_type = F_UNLCK; memset(&lk, 0, sizeof(struct flock));
lk.l_whence = SEEK_SET;
ret = fcntl(l->u.f.fd, F_OFD_SETLK, &lk); lk.l_type = F_UNLCK;
if (ret < 0) { lk.l_whence = SEEK_SET;
if (errno == EINVAL)
ret = flock(l->u.f.fd, LOCK_EX | LOCK_NB);
saved_errno = errno;
}
close(l->u.f.fd); ret = fcntl(l->u.f.fd, F_OFD_SETLK, &lk);
l->u.f.fd = -1; if (ret < 0 && errno == EINVAL)
} else { ret = flock(l->u.f.fd, LOCK_EX | LOCK_NB);
ret = -2;
}
close_prot_errno_disarm(l->u.f.fd);
break; break;
default:
return ret_set_errno(-1, EINVAL);
} }
errno = saved_errno;
return ret; return ret;
} }
...@@ -304,24 +254,16 @@ void lxc_putlock(struct lxc_lock *l) ...@@ -304,24 +254,16 @@ void lxc_putlock(struct lxc_lock *l)
if (!l) if (!l)
return; return;
switch(l->type) { switch (l->type) {
case LXC_LOCK_ANON_SEM: case LXC_LOCK_ANON_SEM:
if (l->u.sem) { if (l->u.sem) {
sem_destroy(l->u.sem); sem_destroy(l->u.sem);
free(l->u.sem); free_disarm(l->u.sem);
l->u.sem = NULL;
} }
break; break;
case LXC_LOCK_FLOCK: case LXC_LOCK_FLOCK:
if (l->u.f.fd != -1) { close_prot_errno_disarm(l->u.f.fd);
close(l->u.f.fd); free_disarm(l->u.f.fname);
l->u.f.fd = -1;
}
free(l->u.f.fname);
l->u.f.fname = NULL;
break; break;
} }
......
...@@ -3012,7 +3012,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna ...@@ -3012,7 +3012,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
int bytes, ret; int bytes, ret;
pid_t child; pid_t child;
int pipefd[2]; int pipefd[2];
char buffer[PATH_MAX] = {0}; char buffer[PATH_MAX] = {};
if (netdev->type != LXC_NET_VETH) if (netdev->type != LXC_NET_VETH)
return log_error_errno(-1, EINVAL, "Network type %d not support for unprivileged use", netdev->type); return log_error_errno(-1, EINVAL, "Network type %d not support for unprivileged use", netdev->type);
......
...@@ -824,6 +824,7 @@ static int btrfs_lxc_rm_rf(const char *path) ...@@ -824,6 +824,7 @@ static int btrfs_lxc_rm_rf(const char *path)
ERROR("Out of memory"); ERROR("Out of memory");
free_btrfs_tree(tree); free_btrfs_tree(tree);
close(fd); close(fd);
return -ENOMEM;
} }
memcpy(name, tmp, name_len); memcpy(name, tmp, name_len);
......
...@@ -97,41 +97,32 @@ static int lvm_snapshot_exec_wrapper(void *data) ...@@ -97,41 +97,32 @@ static int lvm_snapshot_exec_wrapper(void *data)
*/ */
static int do_lvm_create(const char *path, uint64_t size, const char *thinpool) static int do_lvm_create(const char *path, uint64_t size, const char *thinpool)
{ {
__do_free char *pathdup = NULL;
int len, ret; int len, ret;
char *pathdup, *vg, *lv; char *vg, *lv;
char cmd_output[PATH_MAX]; char cmd_output[PATH_MAX];
char sz[24]; char sz[24];
__do_free char *tp = NULL; __do_free char *tp = NULL;
struct lvcreate_args cmd_args = {0}; struct lvcreate_args cmd_args = {0};
ret = snprintf(sz, 24, "%" PRIu64 "b", size); ret = snprintf(sz, 24, "%" PRIu64 "b", size);
if (ret < 0 || ret >= 24) { if (ret < 0 || ret >= 24)
ERROR("Failed to create string: %d", ret); return log_error(-EIO, "Failed to create string: %d", ret);
return -1;
}
pathdup = strdup(path); pathdup = strdup(path);
if (!pathdup) { if (!pathdup)
ERROR("Failed to duplicate string \"%s\"", path); return log_error(-ENOMEM, "Failed to duplicate string \"%s\"", path);
return -1;
}
lv = strrchr(pathdup, '/'); lv = strrchr(pathdup, '/');
if (!lv) { if (!lv)
ERROR("Failed to detect \"/\" in string \"%s\"", pathdup); return log_error(-EINVAL, "Failed to detect \"/\" in string \"%s\"", pathdup);
free(pathdup);
return -1;
}
*lv = '\0'; *lv = '\0';
lv++; lv++;
TRACE("Parsed logical volume \"%s\"", lv); TRACE("Parsed logical volume \"%s\"", lv);
vg = strrchr(pathdup, '/'); vg = strrchr(pathdup, '/');
if (!vg) { if (!vg)
ERROR("Failed to detect \"/\" in string \"%s\"", pathdup); return log_error(-EINVAL, "Failed to detect \"/\" in string \"%s\"", pathdup);
free(pathdup);
return -1;
}
vg++; vg++;
TRACE("Parsed volume group \"%s\"", vg); TRACE("Parsed volume group \"%s\"", vg);
...@@ -140,18 +131,13 @@ static int do_lvm_create(const char *path, uint64_t size, const char *thinpool) ...@@ -140,18 +131,13 @@ static int do_lvm_create(const char *path, uint64_t size, const char *thinpool)
tp = must_realloc(NULL, len); tp = must_realloc(NULL, len);
ret = snprintf(tp, len, "%s/%s", pathdup, thinpool); ret = snprintf(tp, len, "%s/%s", pathdup, thinpool);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len)
ERROR("Failed to create string: %d", ret); return log_error(-EIO, "Failed to create string: %d", ret);
free(pathdup);
return -1;
}
ret = lvm_is_thin_pool(tp); ret = lvm_is_thin_pool(tp);
TRACE("got %d for thin pool at path: %s", ret, tp); TRACE("got %d for thin pool at path: %s", ret, tp);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to detect whether \"%s\" is a thinpool", tp); return log_error(-EINVAL, "Failed to detect whether \"%s\" is a thinpool", tp);
free(pathdup);
return -1;
} else if (!ret) { } else if (!ret) {
TRACE("Detected that \"%s\" is not a thinpool", tp); TRACE("Detected that \"%s\" is not a thinpool", tp);
tp = NULL; tp = NULL;
...@@ -165,30 +151,23 @@ static int do_lvm_create(const char *path, uint64_t size, const char *thinpool) ...@@ -165,30 +151,23 @@ static int do_lvm_create(const char *path, uint64_t size, const char *thinpool)
cmd_args.lv = lv; cmd_args.lv = lv;
cmd_args.size = sz; cmd_args.size = sz;
cmd_args.sigwipe = true; cmd_args.sigwipe = true;
TRACE("Creating new lvm storage volume \"%s\" on volume group \"%s\" " TRACE("Creating new lvm storage volume \"%s\" on volume group \"%s\" of size \"%s\"", lv, vg, sz);
"of size \"%s\"", lv, vg, sz); ret = run_command_status(cmd_output, sizeof(cmd_output), lvm_create_exec_wrapper,
ret = run_command_status(cmd_output, sizeof(cmd_output), (void *)&cmd_args);
lvm_create_exec_wrapper, (void *)&cmd_args);
/* If lvcreate is old and doesn't support signature wiping, try again without it. /* If lvcreate is old and doesn't support signature wiping, try again without it.
* Test for exit code EINVALID_CMD_LINE(3) of lvcreate command. * Test for exit code EINVALID_CMD_LINE(3) of lvcreate command.
*/ */
if (WIFEXITED(ret) && WEXITSTATUS(ret) == 3) { if (WIFEXITED(ret) && WEXITSTATUS(ret) == 3) {
cmd_args.sigwipe = false; cmd_args.sigwipe = false;
ret = run_command(cmd_output, sizeof(cmd_output), ret = run_command(cmd_output, sizeof(cmd_output), lvm_create_exec_wrapper,
lvm_create_exec_wrapper, (void *)&cmd_args); (void *)&cmd_args);
} }
if (ret != 0) { if (ret != 0)
ERROR("Failed to create logical volume \"%s\": %s", lv, return log_error(-1, "Failed to create logical volume \"%s\": %s", lv, cmd_output);
cmd_output); TRACE("Created new lvm storage volume \"%s\" on volume group \"%s\" of size \"%s\"", lv, vg, sz);
free(pathdup);
return -1;
}
TRACE("Created new lvm storage volume \"%s\" on volume group \"%s\" "
"of size \"%s\"", lv, vg, sz);
free(pathdup);
return ret; return ret;
} }
......
...@@ -907,21 +907,21 @@ int parse_byte_size_string(const char *s, int64_t *converted) ...@@ -907,21 +907,21 @@ int parse_byte_size_string(const char *s, int64_t *converted)
char suffix[3] = {0}; char suffix[3] = {0};
if (!s || !strcmp(s, "")) if (!s || !strcmp(s, ""))
return -EINVAL; return ret_errno(EINVAL);
end = stpncpy(dup, s, sizeof(dup) - 1); end = stpncpy(dup, s, sizeof(dup) - 1);
if (*end != '\0') if (*end != '\0')
return -EINVAL; return ret_errno(EINVAL);
if (isdigit(*(end - 1))) if (isdigit(*(end - 1)))
suffix_len = 0; suffix_len = 0;
else if (isalpha(*(end - 1))) else if (isalpha(*(end - 1)))
suffix_len = 1; suffix_len = 1;
else else
return -EINVAL; return ret_errno(EINVAL);
if (suffix_len > 0 && (end - 2) == dup && !isdigit(*(end - 2))) if (suffix_len > 0 && (end - 2) == dup && !isdigit(*(end - 2)))
return -EINVAL; return ret_errno(EINVAL);
if (suffix_len > 0 && isalpha(*(end - 2))) if (suffix_len > 0 && isalpha(*(end - 2)))
suffix_len++; suffix_len++;
...@@ -934,8 +934,8 @@ int parse_byte_size_string(const char *s, int64_t *converted) ...@@ -934,8 +934,8 @@ int parse_byte_size_string(const char *s, int64_t *converted)
dup[lxc_char_right_gc(dup, strlen(dup))] = '\0'; dup[lxc_char_right_gc(dup, strlen(dup))] = '\0';
ret = lxc_safe_long_long(dup, &conv); ret = lxc_safe_long_long(dup, &conv);
if (ret < 0) if (ret)
return -ret; return ret;
if (suffix_len != 2) { if (suffix_len != 2) {
*converted = conv; *converted = conv;
...@@ -949,11 +949,11 @@ int parse_byte_size_string(const char *s, int64_t *converted) ...@@ -949,11 +949,11 @@ int parse_byte_size_string(const char *s, int64_t *converted)
else if (strcasecmp(suffix, "GB") == 0) else if (strcasecmp(suffix, "GB") == 0)
mltpl = 1024 * 1024 * 1024; mltpl = 1024 * 1024 * 1024;
else else
return -EINVAL; return ret_errno(EINVAL);
overflow = conv * mltpl; overflow = conv * mltpl;
if (conv != 0 && (overflow / conv) != mltpl) if (conv != 0 && (overflow / conv) != mltpl)
return -ERANGE; return ret_errno(ERANGE);
*converted = overflow; *converted = overflow;
return 0; return 0;
......
...@@ -240,7 +240,9 @@ int mkdir_p(const char *dir, mode_t mode) ...@@ -240,7 +240,9 @@ int mkdir_p(const char *dir, mode_t mode)
char *get_rundir() char *get_rundir()
{ {
char *rundir; __do_free char *rundir = NULL;
char *static_rundir;
int ret;
size_t len; size_t len;
const char *homedir; const char *homedir;
struct stat sb; struct stat sb;
...@@ -251,9 +253,9 @@ char *get_rundir() ...@@ -251,9 +253,9 @@ char *get_rundir()
if (geteuid() == sb.st_uid || getegid() == sb.st_gid) if (geteuid() == sb.st_uid || getegid() == sb.st_gid)
return strdup(RUNTIME_PATH); return strdup(RUNTIME_PATH);
rundir = getenv("XDG_RUNTIME_DIR"); static_rundir = getenv("XDG_RUNTIME_DIR");
if (rundir) if (static_rundir)
return strdup(rundir); return strdup(static_rundir);
INFO("XDG_RUNTIME_DIR isn't set in the environment"); INFO("XDG_RUNTIME_DIR isn't set in the environment");
homedir = getenv("HOME"); homedir = getenv("HOME");
...@@ -265,8 +267,11 @@ char *get_rundir() ...@@ -265,8 +267,11 @@ char *get_rundir()
if (!rundir) if (!rundir)
return NULL; return NULL;
snprintf(rundir, len, "%s/.cache/lxc/run/", homedir); ret = snprintf(rundir, len, "%s/.cache/lxc/run/", homedir);
return rundir; if (ret < 0 || (size_t)ret >= len)
return ret_set_errno(NULL, EIO);
return move_ptr(rundir);
} }
int wait_for_pid(pid_t pid) int wait_for_pid(pid_t pid)
...@@ -1089,7 +1094,9 @@ int __safe_mount_beneath_at(int beneath_fd, const char *src, const char *dst, co ...@@ -1089,7 +1094,9 @@ int __safe_mount_beneath_at(int beneath_fd, const char *src, const char *dst, co
source_fd = openat2(beneath_fd, src, &how, sizeof(how)); source_fd = openat2(beneath_fd, src, &how, sizeof(how));
if (source_fd < 0) if (source_fd < 0)
return -errno; return -errno;
snprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", source_fd); ret = snprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", source_fd);
if (ret < 0 || ret >= sizeof(src_buf))
return -EIO;
} else { } else {
src_buf[0] = '\0'; src_buf[0] = '\0';
} }
...@@ -1372,10 +1379,8 @@ int lxc_preserve_ns(const int pid, const char *ns) ...@@ -1372,10 +1379,8 @@ int lxc_preserve_ns(const int pid, const char *ns)
ret = snprintf(path, __NS_PATH_LEN, "/proc/%d/ns%s%s", pid, ret = snprintf(path, __NS_PATH_LEN, "/proc/%d/ns%s%s", pid,
!ns || strcmp(ns, "") == 0 ? "" : "/", !ns || strcmp(ns, "") == 0 ? "" : "/",
!ns || strcmp(ns, "") == 0 ? "" : ns); !ns || strcmp(ns, "") == 0 ? "" : ns);
if (ret < 0 || (size_t)ret >= __NS_PATH_LEN) { if (ret < 0 || (size_t)ret >= __NS_PATH_LEN)
errno = EFBIG; return ret_errno(EIO);
return -1;
}
return open(path, O_RDONLY | O_CLOEXEC); return open(path, O_RDONLY | O_CLOEXEC);
} }
......
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