Skip to content

Commit

Permalink
tools: move lxc-unshare to API symbols only
Browse files Browse the repository at this point in the history
Closes #2073.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
  • Loading branch information
Christian Brauner committed Feb 6, 2018
1 parent b678c6d commit d567a9a
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 18 deletions.
77 changes: 59 additions & 18 deletions src/lxc/tools/lxc_unshare.c
Expand Up @@ -20,30 +20,27 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"

#include <stdio.h>
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <libgen.h>
#include <netinet/in.h>
#include <pwd.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/eventfd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "caps.h"
#include "cgroup.h"
#include "error.h"
#include "log.h"
#include "namespace.h"
#include "network.h"
#include "utils.h"
#include "arguments.h"
#include "tool_utils.h"

struct my_iflist
{
Expand All @@ -67,7 +64,7 @@ static void usage(char *cmd)

static bool lookup_user(const char *optarg, uid_t *uid)
{
char name[MAXPATHLEN];
char name[TOOL_MAXPATHLEN];
struct passwd *pwent = NULL;

if (!optarg || (optarg[0] == '\0'))
Expand Down Expand Up @@ -147,11 +144,34 @@ static int do_start(void *arg)
return 1;
}

int write_id_mapping(pid_t pid, const char *buf, size_t buf_size)
{
char path[TOOL_MAXPATHLEN];
int fd, ret;


ret = snprintf(path, TOOL_MAXPATHLEN, "/proc/%d/uid_map", pid);
if (ret < 0 || ret >= TOOL_MAXPATHLEN)
return -E2BIG;

fd = open(path, O_WRONLY);
if (fd < 0)
return -1;

errno = 0;
ret = lxc_write_nointr(fd, buf, buf_size);
close(fd);
if (ret < 0 || (size_t)ret != buf_size)
return -1;

return 0;
}

int main(int argc, char *argv[])
{
char *del;
char **it, **args;
int opt, status;
int opt;
int ret;
char *namespaces = NULL;
int flags = 0, daemonize = 0;
Expand Down Expand Up @@ -284,7 +304,7 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}

ret = write_id_mapping(ID_TYPE_UID, pid, umap, strlen(umap));
ret = write_id_mapping(pid, umap, strlen(umap));
if (ret < 0) {
close(start_arg.wait_fd);
fprintf(stderr, "uid mapping failed\n");
Expand All @@ -301,19 +321,40 @@ int main(int argc, char *argv[])

if (my_iflist) {
for (tmpif = my_iflist; tmpif; tmpif = tmpif->mi_next) {
if (lxc_netdev_move_by_name(tmpif->mi_ifname, pid, NULL) < 0)
fprintf(stderr,"Could not move interface %s into container %d: %s\n", tmpif->mi_ifname, pid, strerror(errno));
pid_t pid;

pid = fork();
if (pid < 0)
fprintf(stderr, "Failed to move network device "
"\"%s\" to network namespace\n",
tmpif->mi_ifname);

if (pid == 0) {
char buf[256];

ret = snprintf(buf, 256, "%d", pid);
if (ret < 0 || ret >= 256)
exit(EXIT_FAILURE);

execlp("ip", "ip", "link", "set", "dev", tmpif->mi_ifname, "netns", buf, (char *)NULL);
exit(EXIT_FAILURE);
}

if (wait_for_pid(pid) != 0)
fprintf(stderr, "Could not move interface %s "
"into container %d: %s\n",
tmpif->mi_ifname, pid, strerror(errno));
}
}

if (daemonize)
exit(EXIT_SUCCESS);

if (waitpid(pid, &status, 0) < 0) {
if (wait_for_pid(pid) != 0) {
fprintf(stderr, "failed to wait for '%d'\n", pid);
exit(EXIT_FAILURE);
}

/* Call exit() directly on this function because it retuns an exit code. */
exit(lxc_error_set_and_log(pid, status));
exit(EXIT_SUCCESS);
}
63 changes: 63 additions & 0 deletions src/lxc/tools/tool_utils.c
Expand Up @@ -31,6 +31,7 @@
#include <strings.h>
#include <unistd.h>
#include <linux/sched.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
Expand All @@ -42,6 +43,7 @@

#include <lxc/lxccontainer.h>

#include "arguments.h"
#include "tool_utils.h"

int lxc_fill_elevated_privileges(char *flaglist, int *flags)
Expand Down Expand Up @@ -1131,3 +1133,64 @@ ssize_t lxc_read_nointr(int fd, void* buf, size_t count)
goto again;
return ret;
}

static int mount_fs(const char *source, const char *target, const char *type)
{
/* the umount may fail */
if (umount(target) < 0)

if (mount(source, target, type, 0, NULL) < 0)
return -1;

return 0;
}

void lxc_setup_fs(void)
{
(void)mount_fs("proc", "/proc", "proc");

/* if /dev has been populated by us, /dev/shm does not exist */
if (access("/dev/shm", F_OK))
(void)mkdir("/dev/shm", 0777);

/* if we can't mount /dev/shm, continue anyway */
(void)mount_fs("shmfs", "/dev/shm", "tmpfs");

/* If we were able to mount /dev/shm, then /dev exists */
/* Sure, but it's read-only per config :) */
if (access("/dev/mqueue", F_OK))
(void)mkdir("/dev/mqueue", 0666);

/* continue even without posix message queue support */
(void)mount_fs("mqueue", "/dev/mqueue", "mqueue");
}

struct clone_arg {
int (*fn)(void *);
void *arg;
};

static int do_clone(void *arg)
{
struct clone_arg *clone_arg = arg;
return clone_arg->fn(clone_arg->arg);
}

pid_t lxc_clone(int (*fn)(void *), void *arg, int flags)
{
struct clone_arg clone_arg = {
.fn = fn,
.arg = arg,
};

size_t stack_size = lxc_getpagesize();
void *stack = alloca(stack_size);
pid_t ret;

#ifdef __ia64__
ret = __clone2(do_clone, stack, stack_size, flags | SIGCHLD, &clone_arg);
#else
ret = clone(do_clone, stack + stack_size, flags | SIGCHLD, &clone_arg);
#endif
return ret;
}
24 changes: 24 additions & 0 deletions src/lxc/tools/tool_utils.h
Expand Up @@ -176,4 +176,28 @@ extern ssize_t lxc_write_nointr(int fd, const void* buf, size_t count);

extern char *get_rundir();

extern void lxc_setup_fs(void);

static inline uint64_t lxc_getpagesize(void)
{
int64_t pgsz;

pgsz = sysconf(_SC_PAGESIZE);
if (pgsz <= 0)
pgsz = 1 << 12;

return pgsz;
}

#if defined(__ia64__)
int __clone2(int (*__fn) (void *__arg), void *__child_stack_base,
size_t __child_stack_size, int __flags, void *__arg, ...);
#else
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
#endif

extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags);

#endif /* __LXC_UTILS_H */

0 comments on commit d567a9a

Please sign in to comment.