Commit 42f055d0 by Serge Hallyn Committed by GitHub

Merge pull request #1801 from brauner/2017-09-09/userns_exec

conf: add userns_exec_full()
parents 17872651 ed8704d0
......@@ -782,7 +782,7 @@ static const struct dev_symlinks dev_symlinks[] = {
{"/proc/self/fd/2", "stderr"},
};
static int setup_dev_symlinks(const struct lxc_rootfs *rootfs)
static int lxc_setup_dev_symlinks(const struct lxc_rootfs *rootfs)
{
char path[MAXPATHLEN];
int ret,i;
......@@ -3220,13 +3220,16 @@ int lxc_setup(struct lxc_handler *handler)
}
}
if (!lxc_conf->is_execute && lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console, lxc_conf->ttydir)) {
ERROR("failed to setup the console for '%s'", name);
ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console,
lxc_conf->ttydir);
if (ret < 0) {
ERROR("Failed to setup console");
return -1;
}
if (!lxc_conf->is_execute && setup_dev_symlinks(&lxc_conf->rootfs)) {
ERROR("failed to setup /dev symlinks for '%s'", name);
ret = lxc_setup_dev_symlinks(&lxc_conf->rootfs);
if (ret < 0) {
ERROR("Failed to setup /dev symlinks");
return -1;
}
......@@ -3816,8 +3819,7 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
ret = lxc_map_ids(idmap, pid);
if (ret < 0) {
ERROR("error setting up {g,u}id mappings for child process "
"\"%d\"",
pid);
"\"%d\"", pid);
goto on_error;
}
......@@ -3849,6 +3851,184 @@ on_error:
return ret;
}
int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data,
const char *fn_name)
{
pid_t pid;
uid_t euid, egid;
struct userns_fn_data d;
int p[2];
struct id_map *map;
struct lxc_list *cur;
char c = '1';
int ret = -1;
struct lxc_list *idmap = NULL, *tmplist = NULL;
struct id_map *container_root_uid = NULL, *container_root_gid = NULL,
*host_uid_map = NULL, *host_gid_map = NULL;
ret = pipe(p);
if (ret < 0) {
SYSERROR("opening pipe");
return -1;
}
d.fn = fn;
d.fn_name = fn_name;
d.arg = data;
d.p[0] = p[0];
d.p[1] = p[1];
/* Clone child in new user namespace. */
pid = lxc_clone(run_userns_fn, &d, CLONE_NEWUSER);
if (pid < 0) {
ERROR("failed to clone child process in new user namespace");
goto on_error;
}
close(p[0]);
p[0] = -1;
euid = geteuid();
egid = getegid();
/* Allocate new {g,u}id map list. */
idmap = malloc(sizeof(*idmap));
if (!idmap)
goto on_error;
lxc_list_init(idmap);
/* Find container root. */
lxc_list_for_each(cur, &conf->id_map) {
struct id_map *tmpmap;
tmplist = malloc(sizeof(*tmplist));
if (!tmplist)
goto on_error;
tmpmap = malloc(sizeof(*tmpmap));
if (!tmpmap) {
free(tmplist);
goto on_error;
}
memset(tmpmap, 0, sizeof(*tmpmap));
memcpy(tmpmap, cur->elem, sizeof(*tmpmap));
tmplist->elem = tmpmap;
lxc_list_add_tail(idmap, tmplist);
map = cur->elem;
if (map->idtype == ID_TYPE_UID)
if (euid >= map->hostid && euid < map->hostid + map->range)
host_uid_map = map;
if (map->idtype == ID_TYPE_GID)
if (egid >= map->hostid && egid < map->hostid + map->range)
host_gid_map = map;
if (map->nsid != 0)
continue;
if (map->idtype == ID_TYPE_UID)
if (container_root_uid == NULL)
container_root_uid = map;
if (map->idtype == ID_TYPE_GID)
if (container_root_gid == NULL)
container_root_gid = map;
}
if (!container_root_uid || !container_root_gid) {
ERROR("No mapping for container root found");
goto on_error;
}
/* Check whether the {g,u}id of the user has a mapping. */
if (!host_uid_map)
host_uid_map = idmap_add(conf, euid, ID_TYPE_UID);
else
host_uid_map = container_root_uid;
if (!host_gid_map)
host_gid_map = idmap_add(conf, egid, ID_TYPE_GID);
else
host_gid_map = container_root_gid;
if (!host_uid_map) {
DEBUG("Failed to find mapping for uid %d", euid);
goto on_error;
}
if (!host_gid_map) {
DEBUG("Failed to find mapping for gid %d", egid);
goto on_error;
}
if (host_uid_map && (host_uid_map != container_root_uid)) {
/* Add container root to the map. */
tmplist = malloc(sizeof(*tmplist));
if (!tmplist)
goto on_error;
lxc_list_add_elem(tmplist, host_uid_map);
lxc_list_add_tail(idmap, tmplist);
}
/* idmap will now keep track of that memory. */
host_uid_map = NULL;
if (host_gid_map && (host_gid_map != container_root_gid)) {
tmplist = malloc(sizeof(*tmplist));
if (!tmplist)
goto on_error;
lxc_list_add_elem(tmplist, host_gid_map);
lxc_list_add_tail(idmap, tmplist);
}
/* idmap will now keep track of that memory. */
host_gid_map = NULL;
if (lxc_log_get_level() == LXC_LOG_LEVEL_TRACE ||
conf->loglevel == LXC_LOG_LEVEL_TRACE) {
lxc_list_for_each(cur, idmap) {
map = cur->elem;
TRACE("establishing %cid mapping for \"%d\" in new "
"user namespace: nsuid %lu - hostid %lu - range "
"%lu",
(map->idtype == ID_TYPE_UID) ? 'u' : 'g', pid,
map->nsid, map->hostid, map->range);
}
}
/* Set up {g,u}id mapping for user namespace of child process. */
ret = lxc_map_ids(idmap, pid);
if (ret < 0) {
ERROR("error setting up {g,u}id mappings for child process "
"\"%d\"", pid);
goto on_error;
}
/* Tell child to proceed. */
if (write(p[1], &c, 1) != 1) {
SYSERROR("failed telling child process \"%d\" to proceed", pid);
goto on_error;
}
/* Wait for child to finish. */
ret = wait_for_pid(pid);
on_error:
if (idmap)
lxc_free_idmap(idmap);
if (host_uid_map && (host_uid_map != container_root_uid))
free(host_uid_map);
if (host_gid_map && (host_gid_map != container_root_gid))
free(host_gid_map);
if (p[0] != -1)
close(p[0]);
close(p[1]);
return ret;
}
/* not thread-safe, do not use from api without first forking */
static char* getuname(void)
{
......
......@@ -381,6 +381,8 @@ extern int chown_mapped_root(char *path, struct lxc_conf *conf);
extern int lxc_ttys_shift_ids(struct lxc_conf *c);
extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
const char *fn_name);
extern int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *),
void *data, const char *fn_name);
extern int parse_mntopts(const char *mntopts, unsigned long *mntflags,
char **mntdata);
extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
......
......@@ -1920,42 +1920,51 @@ struct parse_line_conf {
static int parse_line(char *buffer, void *data)
{
struct lxc_config_t *config;
char *dot, *key, *line, *linep, *value;
struct parse_line_conf *plc = data;
bool empty_line;
struct lxc_config_t *config;
int ret = 0;
char *dup = buffer;
struct parse_line_conf *plc = data;
if (lxc_is_line_empty(buffer))
return 0;
/* If there are newlines in the config file we should keep them. */
empty_line = lxc_is_line_empty(dup);
if (empty_line)
dup = "\n";
/* We have to dup the buffer otherwise, at the re-exec for reboot we
* modified the original string on the stack by replacing '=' by '\0'
* below.
*/
linep = line = strdup(buffer);
linep = line = strdup(dup);
if (!line)
return -1;
if (!plc->from_include)
if ((ret = append_unexp_config_line(line, plc->conf)))
goto out;
if (!plc->from_include) {
ret = append_unexp_config_line(line, plc->conf);
if (ret < 0)
goto on_error;
}
if (empty_line)
return 0;
line += lxc_char_left_gc(line, strlen(line));
/* ignore comments */
if (line[0] == '#')
goto out;
goto on_error;
/* martian option - don't add it to the config itself */
if (strncmp(line, "lxc.", 4))
goto out;
goto on_error;
ret = -1;
dot = strstr(line, "=");
dot = strchr(line, '=');
if (!dot) {
ERROR("invalid configuration line: %s", line);
goto out;
ERROR("Invalid configuration line: %s", line);
goto on_error;
}
*dot = '\0';
......@@ -1980,7 +1989,7 @@ static int parse_line(char *buffer, void *data)
config = lxc_get_config(key);
if (!config) {
ERROR("Unknown configuration key \"%s\"", key);
goto out;
goto on_error;
}
/* [START]: REMOVE IN LXC 3.0 */
......@@ -1998,7 +2007,7 @@ static int parse_line(char *buffer, void *data)
ret = config->set(key, value, plc->conf, NULL);
out:
on_error:
free(linep);
return ret;
}
......
......@@ -92,8 +92,6 @@ int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
/* Move beyond \0. */
slide++;
/* align */
window = slide;
/* Validate that only whitespace follows. */
slide += strspn(slide, " \t\r");
/* If there was only one whitespace then we whiped it with our \0 above.
......@@ -118,8 +116,6 @@ int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
/* Move beyond \0. */
slide++;
/* align */
window = slide;
/* Validate that only whitespace follows. */
slide += strspn(slide, " \t\r");
/* If there was only one whitespace then we whiped it with our \0 above.
......
......@@ -228,11 +228,6 @@ extern int lxc_console_mainloop_add(struct lxc_epoll_descr *descr,
{
struct lxc_console *console = &conf->console;
if (conf->is_execute) {
INFO("no console for lxc-execute.");
return 0;
}
if (!conf->rootfs.path) {
INFO("no rootfs, no console.");
return 0;
......@@ -480,7 +475,6 @@ static int lxc_console_peer_default(struct lxc_console *console)
console->tios = malloc(sizeof(*console->tios));
if (!console->tios) {
SYSERROR("failed to allocate memory");
ret = -ENOMEM;
goto on_error1;
}
......@@ -492,7 +486,6 @@ static int lxc_console_peer_default(struct lxc_console *console)
on_error2:
free(console->tios);
console->tios = NULL;
ret = -ENOTTY;
on_error1:
close(console->peer);
......@@ -528,11 +521,6 @@ int lxc_console_create(struct lxc_conf *conf)
struct lxc_console *console = &conf->console;
int ret;
if (conf->is_execute) {
INFO("not allocating a console device for lxc-execute.");
return 0;
}
if (!conf->rootfs.path) {
INFO("container does not have a rootfs, console device will be shared with the host");
return 0;
......
......@@ -551,7 +551,7 @@ static void exec_criu(struct criu_opts *opts)
external_not_veth = false;
}
if (n->name) {
if (n->name[0] != '\0') {
if (strlen(n->name) >= sizeof(eth))
goto err;
strncpy(eth, n->name, sizeof(eth));
......
......@@ -638,7 +638,7 @@ static int count_entries(char *buf, off_t len, char *name, char *net_type, char
{
int count = 0;
bool owner = false;;
char *buf_end = &buf[len];
char *buf_end;
buf_end = &buf[len];
while ((buf = find_line(buf, buf_end, name, net_type, net_link, NULL,
......
......@@ -2569,12 +2569,17 @@ static bool has_snapshots(struct lxc_container *c)
}
static bool do_destroy_container(struct lxc_conf *conf) {
int ret;
if (am_unpriv()) {
if (userns_exec_1(conf, storage_destroy_wrapper, conf,
"storage_destroy_wrapper") < 0)
ret = userns_exec_full(conf, storage_destroy_wrapper, conf,
"storage_destroy_wrapper");
if (ret < 0)
return false;
return true;
}
return storage_destroy(conf);
}
......@@ -2708,8 +2713,8 @@ static bool container_destroy(struct lxc_container *c,
if (ret < 0 || (size_t)ret >= len)
goto out;
if (am_unpriv())
ret = userns_exec_1(conf, lxc_rmdir_onedev_wrapper, path,
"lxc_rmdir_onedev_wrapper");
ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
"lxc_rmdir_onedev_wrapper");
else
ret = lxc_rmdir_onedev(path, "snaps");
if (ret < 0) {
......@@ -3551,8 +3556,8 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
data.flags = flags;
data.hookargs = hookargs;
if (am_unpriv())
ret = userns_exec_1(c->lxc_conf, clone_update_rootfs_wrapper,
&data, "clone_update_rootfs_wrapper");
ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
&data, "clone_update_rootfs_wrapper");
else
ret = clone_update_rootfs(&data);
if (ret < 0)
......
......@@ -243,7 +243,6 @@ int lxc_monitor_open(const char *lxcpath)
ERROR("Failed to connect to monitor socket: %s.", strerror(errno));
goto on_error;
}
ret = 0;
return fd;
......
......@@ -935,7 +935,6 @@ int netdev_get_mtu(int ifindex)
goto out;
recv_len = err;
err = 0;
/* Satisfy the typing for the netlink macros */
msg = answer->nlmsghdr;
......@@ -1377,7 +1376,6 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
data = (unsigned char *)sockaddr->sa_data;
while ((*macaddr != '\0') && (i < ETH_ALEN)) {
val = 0;
c = *macaddr++;
if (isdigit(c))
val = c - '0';
......
......@@ -1142,7 +1142,7 @@ static int lxc_spawn(struct lxc_handler *handler)
bool wants_to_map_ids;
int saved_ns_fd[LXC_NS_MAX];
struct lxc_list *id_map;
int failed_before_rename = 0, preserve_mask = 0;
int preserve_mask = 0;
bool cgroups_connected = false;
id_map = &handler->conf->id_map;
......@@ -1256,15 +1256,11 @@ static int lxc_spawn(struct lxc_handler *handler)
goto out_delete_net;
}
if (lxc_sync_wake_child(handler, LXC_SYNC_STARTUP)) {
failed_before_rename = 1;
if (lxc_sync_wake_child(handler, LXC_SYNC_STARTUP))
goto out_delete_net;
}
if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE)) {
failed_before_rename = 1;
if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE))
goto out_delete_net;
}
if (!cgroup_create_legacy(handler)) {
ERROR("Failed to setup legacy cgroups for container \"%s\".", name);
......@@ -1281,9 +1277,6 @@ static int lxc_spawn(struct lxc_handler *handler)
if (!cgroup_chown(handler))
goto out_delete_net;
if (failed_before_rename)
goto out_delete_net;
handler->netnsfd = lxc_preserve_ns(handler->pid, "net");
if (handler->netnsfd < 0) {
ERROR("Failed to preserve network namespace");
......@@ -1596,8 +1589,8 @@ static void lxc_destroy_container_on_signal(struct lxc_handler *handler,
}
if (!handler->am_root)
ret = userns_exec_1(handler->conf, lxc_rmdir_onedev_wrapper,
destroy, "lxc_rmdir_onedev_wrapper");
ret = userns_exec_full(handler->conf, lxc_rmdir_onedev_wrapper,
destroy, "lxc_rmdir_onedev_wrapper");
else
ret = lxc_rmdir_onedev(destroy, NULL);
......@@ -1615,9 +1608,12 @@ static int lxc_rmdir_onedev_wrapper(void *data)
}
static bool do_destroy_container(struct lxc_handler *handler) {
int ret;
if (!handler->am_root) {
if (userns_exec_1(handler->conf, storage_destroy_wrapper,
handler->conf, "storage_destroy_wrapper") < 0)
ret = userns_exec_full(handler->conf, storage_destroy_wrapper,
handler->conf, "storage_destroy_wrapper");
if (ret < 0)
return false;
return true;
......
......@@ -164,8 +164,8 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
rdata.src = odelta;
rdata.dest = ndelta;
if (am_unpriv())
ret = userns_exec_1(conf, lxc_rsync_delta_wrapper,
&rdata, "lxc_rsync_delta_wrapper");
ret = userns_exec_full(conf, lxc_rsync_delta_wrapper,
&rdata, "lxc_rsync_delta_wrapper");
else
ret = run_command(cmd_output, sizeof(cmd_output),
lxc_rsync_delta_wrapper,
......
......@@ -434,8 +434,8 @@ bool btrfs_create_clone(struct lxc_conf *conf, struct lxc_storage *orig,
data.orig = orig;
data.new = new;
if (am_unpriv()) {
ret = userns_exec_1(conf, lxc_storage_rsync_exec_wrapper, &data,
"lxc_storage_rsync_exec_wrapper");
ret = userns_exec_full(conf, lxc_storage_rsync_exec_wrapper,
&data, "lxc_storage_rsync_exec_wrapper");
if (ret < 0) {
ERROR("Failed to rsync from \"%s\" into \"%s\"",
orig->dest, new->dest);
......
......@@ -109,9 +109,9 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1;
}
strncpy(delta, new->dest, lastslashidx + 1);
strncpy(delta + lastslashidx, "delta0", sizeof("delta0") - 1);
delta[lastslashidx + sizeof("delta0")] = '\0';
memcpy(delta, new->dest, lastslashidx + 1);
memcpy(delta + lastslashidx, "delta0", sizeof("delta0") - 1);
delta[lastslashidx + sizeof("delta0") - 1] = '\0';
ret = mkdir(delta, 0755);
if (ret < 0 && errno != EEXIST) {
......@@ -141,12 +141,13 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1;
}
strncpy(work, new->dest, lastslashidx + 1);
strncpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
work[lastslashidx + sizeof("olwork")] = '\0';
memcpy(work, new->dest, lastslashidx + 1);
memcpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
work[lastslashidx + sizeof("olwork") - 1] = '\0';
if (mkdir(work, 0755) < 0) {
SYSERROR("error: mkdir %s", work);
ret = mkdir(work, 0755);
if (ret < 0) {
SYSERROR("Failed to create directory \"%s\"", work);
free(delta);
free(work);
return -1;
......@@ -200,9 +201,8 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
nsrc = strchr(osrc, ':') + 1;
if ((nsrc != osrc + 8) && (nsrc != osrc + 10)) {
ERROR("Detected \":\" in \"%s\" at wrong position", osrc);
free(osrc);
ERROR("Detected \":\" in \"%s\" at wrong position",
osrc);
return -22;
}
......@@ -219,9 +219,9 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
ret = mkdir(ndelta, 0755);
if (ret < 0 && errno != EEXIST) {
SYSERROR("Failed to create directory \"%s\"", ndelta);
free(osrc);
free(ndelta);
SYSERROR("Failed to create directory \"%s\"", ndelta);
return -1;
}
......@@ -237,9 +237,9 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
*/
lastslash = strrchr(ndelta, '/');
if (!lastslash) {
ERROR("Failed to detect \"/\" in \"%s\"", ndelta);
free(osrc);
free(ndelta);
ERROR("Failed to detect \"/\" in \"%s\"", ndelta);
return -1;
}
lastslash++;
......@@ -253,16 +253,16 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1;
}
strncpy(work, ndelta, lastslashidx + 1);
strncpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
work[lastslashidx + sizeof("olwork")] = '\0';
memcpy(work, ndelta, lastslashidx + 1);
memcpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
work[lastslashidx + sizeof("olwork") - 1] = '\0';
ret = mkdir(work, 0755);
if (ret < 0 && errno != EEXIST) {
SYSERROR("Failed to create directory \"%s\"", ndelta);
free(osrc);
free(ndelta);
free(work);
SYSERROR("Failed to create directory \"%s\"", ndelta);
return -1;
}
......@@ -322,7 +322,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
s1 = strrchr(clean_old_path, '/');
if (!s1) {
ERROR("Failed to detect \"/\" in string \"%s\"", s1);
ERROR("Failed to detect \"/\" in string \"%s\"", clean_old_path);
free(clean_old_path);
free(clean_new_path);
return -1;
......@@ -330,7 +330,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
s2 = strrchr(clean_new_path, '/');
if (!s2) {
ERROR("Failed to detect \"/\" in string \"%s\"", s2);
ERROR("Failed to detect \"/\" in string \"%s\"", clean_new_path);
free(clean_old_path);
free(clean_new_path);
return -1;
......@@ -417,8 +417,8 @@ int ovl_create(struct lxc_storage *bdev, const char *dest, const char *n,
return -1;
}
strncpy(delta, dest, len);
strncpy(delta + len - 6, "delta0", sizeof("delta0") - 1);
memcpy(delta, dest, len);
memcpy(delta + len - 6, "delta0", sizeof("delta0") - 1);
delta[len + sizeof("delta0")] = '\0';
ret = mkdir_p(delta, 0755);
......@@ -575,9 +575,9 @@ int ovl_mount(struct lxc_storage *bdev)
return -22;
}
strncpy(work, upper, lastslashidx + 1);
strncpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
work[lastslashidx + sizeof("olwork")] = '\0';
memcpy(work, upper, lastslashidx + 1);
memcpy(work + lastslashidx, "olwork", sizeof("olwork") - 1);
work[lastslashidx + sizeof("olwork") - 1] = '\0';
ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata);
if (ret < 0) {
......@@ -747,8 +747,9 @@ int ovl_mkdir(const struct mntent *mntent, const struct lxc_rootfs *rootfs,
char lxcpath[MAXPATHLEN];
char **opts;
int ret;
size_t arrlen, dirlen, i, len, rootfslen;
size_t arrlen, i, len, rootfslen;
int fret = -1;
size_t dirlen = 0;
char *rootfs_dir = NULL, *rootfs_path = NULL, *upperdir = NULL,
*workdir = NULL;
......@@ -772,8 +773,7 @@ int ovl_mkdir(const struct mntent *mntent, const struct lxc_rootfs *rootfs,
}
if (rootfs_path) {
ret =
snprintf(lxcpath, MAXPATHLEN, "%s/%s", lxc_path, lxc_name);
ret = snprintf(lxcpath, MAXPATHLEN, "%s/%s", lxc_path, lxc_name);
if (ret < 0 || ret >= MAXPATHLEN)
goto err;
......@@ -971,8 +971,8 @@ static int ovl_do_rsync(const char *src, const char *dest,
rdata.src = (char *)src;
rdata.dest = (char *)dest;
if (am_unpriv())
ret = userns_exec_1(conf, lxc_rsync_exec_wrapper, &rdata,
"lxc_rsync_exec_wrapper");
ret = userns_exec_full(conf, lxc_rsync_exec_wrapper, &rdata,
"lxc_rsync_exec_wrapper");
else
ret = run_command(cmd_output, sizeof(cmd_output),
lxc_rsync_exec_wrapper, (void *)&rdata);
......
......@@ -502,8 +502,9 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
data.orig = orig;
data.new = new;
if (am_unpriv())
ret = userns_exec_1(c->lxc_conf, lxc_storage_rsync_exec_wrapper,
&data, "lxc_storage_rsync_exec_wrapper");
ret = userns_exec_full(c->lxc_conf,
lxc_storage_rsync_exec_wrapper, &data,
"lxc_storage_rsync_exec_wrapper");
else
ret = run_command(cmd_output, sizeof(cmd_output),
lxc_storage_rsync_exec_wrapper, (void *)&data);
......
......@@ -136,7 +136,6 @@ extern struct lxc_storage *storage_create(const char *dest, const char *type,
extern void storage_put(struct lxc_storage *bdev);
extern bool storage_destroy(struct lxc_conf *conf);
/* callback function to be used with userns_exec_1() */
extern int storage_destroy_wrapper(void *data);
extern bool rootfs_is_blockdev(struct lxc_conf *conf);
extern char *lxc_storage_get_path(char *src, const char *prefix);
......
......@@ -228,6 +228,9 @@ int main(int argc, char *argv[])
* dest: del + 1 == OUNT|PID
* src: del + 3 == NT|PID
*/
if (!namespaces)
usage(argv[0]);
while ((del = strstr(namespaces, "MOUNT")))
memmove(del + 1, del + 3, strlen(del) - 2);
......
......@@ -316,10 +316,8 @@ int main(int argc, char *argv[])
argv = &argv[optind];
argc = argc - optind;
if (argc < 1) {
if (argc < 1)
argv = default_args;
argc = 1;
}
if (pipe(pipe1) < 0 || pipe(pipe2) < 0) {
perror("pipe");
......@@ -367,10 +365,9 @@ int main(int argc, char *argv[])
buf[0] = '1';
if (lxc_map_ids(&active_map, pid)) {
if (lxc_map_ids(&active_map, pid))
fprintf(stderr, "error mapping child\n");
ret = 0;
}
if (write(pipe2[1], buf, 1) < 0) {
perror("write to pipe");
exit(EXIT_FAILURE);
......
......@@ -494,7 +494,6 @@ extern struct lxc_popen_FILE *lxc_popen(const char *command)
int child_std_end = STDOUT_FILENO;
close(parent_end);
parent_end = -1;
if (child_end != child_std_end) {
/* dup2() doesn't dup close-on-exec flag */
......@@ -533,7 +532,6 @@ extern struct lxc_popen_FILE *lxc_popen(const char *command)
/* parent */
close(child_end);
child_end = -1;
if (child_pid < 0) {
ERROR("fork failure");
......@@ -2330,9 +2328,11 @@ int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
/* close the write-end of the pipe */
close(pipefd[1]);
bytes = read(pipefd[0], buf, (buf_size > 0) ? (buf_size - 1) : 0);
if (bytes > 0)
buf[bytes - 1] = '\0';
if (buf && buf_size > 0) {
bytes = read(pipefd[0], buf, buf_size - 1);
if (bytes > 0)
buf[bytes - 1] = '\0';
}
fret = wait_for_pid(child);
/* close the read-end of the pipe */
......
......@@ -188,7 +188,8 @@ int main(int argc, char *argv[]) {
}
modes[i] = tok;
}
modes[i] = NULL;
if (modes)
modes[i] = NULL;
break;
}
default: /* '?' */
......
......@@ -40,10 +40,8 @@ static int destroy_busybox(void)
return -1;
}
if (pid == 0) {
ret = execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL);
// Should not return
perror("execl");
exit(1);
execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL);
exit(EXIT_FAILURE);
}
again:
ret = waitpid(pid, &status, 0);
......@@ -72,10 +70,8 @@ static int create_busybox(void)
return -1;
}
if (pid == 0) {
ret = execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
// Should not return
perror("execl");
exit(1);
execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
exit(EXIT_FAILURE);
}
again:
ret = waitpid(pid, &status, 0);
......
......@@ -38,10 +38,8 @@ static int create_container(void)
return -1;
}
if (pid == 0) {
ret = execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
// Should not return
perror("execl");
exit(1);
execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
exit(EXIT_FAILURE);
}
again:
ret = waitpid(pid, &status, 0);
......
......@@ -38,10 +38,8 @@ static int create_container(void)
return -1;
}
if (pid == 0) {
ret = execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
// Should not return
perror("execl");
exit(1);
execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
exit(EXIT_FAILURE);
}
again:
ret = waitpid(pid, &status, 0);
......
......@@ -40,10 +40,8 @@ static int destroy_container(void)
return -1;
}
if (pid == 0) {
ret = execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL);
// Should not return
perror("execl");
exit(1);
execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL);
exit(EXIT_FAILURE);
}
again:
ret = waitpid(pid, &status, 0);
......@@ -72,10 +70,8 @@ static int create_container(void)
return -1;
}
if (pid == 0) {
ret = execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
// Should not return
perror("execl");
exit(1);
execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
exit(EXIT_FAILURE);
}
again:
ret = waitpid(pid, &status, 0);
......
......@@ -40,10 +40,8 @@ static int destroy_container(void)
return -1;
}
if (pid == 0) {
ret = execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL);
// Should not return
perror("execl");
exit(1);
execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL);
exit(EXIT_FAILURE);
}
again:
ret = waitpid(pid, &status, 0);
......@@ -72,10 +70,8 @@ static int create_container(void)
return -1;
}
if (pid == 0) {
ret = execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
// Should not return
perror("execl");
exit(1);
execlp("lxc-create", "lxc-create", "-t", "busybox", "-n", MYNAME, NULL);
exit(EXIT_FAILURE);
}
again:
ret = waitpid(pid, &status, 0);
......
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