# HG changeset patch # User Rob Landley # Date 1423344742 21600 # Node ID 435f91d71898eef11c80e4c230983592bb0d468a # Parent 39b5bc4e18531e6c84d42cd87fe2337a6599d72d Merge unshare and nsenter (promoting and cleaning up nsenter). Needs more testing, don't have a test environment set up for this yet... diff -r 39b5bc4e1853 -r 435f91d71898 toys/other/nsenter.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toys/other/nsenter.c Sat Feb 07 15:32:22 2015 -0600 @@ -0,0 +1,116 @@ +/* nsenter.c - Enter existing namespaces + * + * Copyright 2014 andy Lutomirski + * + * No standard + * + * unshare.c - run command in new context + * + * Copyright 2011 Rob Landley + * + * No Standard + * + +// Note: flags go in same order (right to left) for shared subset +USE_NSENTER(NEWTOY(nsenter, "<1F(no-fork)t#<1(target)i:(ipc);m:(mount);n:(net);p:(pid);u:(uts);U:(user);", TOYFLAG_USR|TOYFLAG_BIN)) +USE_UNSHARE(NEWTOY(unshare, "<1^imnpuU", TOYFLAG_USR|TOYFLAG_BIN)) + +config UNSHARE + bool "unshare" + default y + depends on TOYBOX_CONTAINER + help + usage: unshare [-imnpuU] COMMAND... + + Create new namespace(s) for this process and its children, so some + attribute is not shared with the parent process. This is part of + Linux Containers. Each process can have its own: + + -i SysV IPC (message queues, semaphores, shared memory) + -m Mount/unmount tree + -n Network address, sockets, routing, iptables + -p Process IDs and init + -u Host and domain names + -U UIDs, GIDs, capabilities + +config NSENTER + bool "nsenter" + default n + help + usage: nsenter [-t pid] [-F] [-i] [-m] [-n] [-p] [-u] [-U] COMMAND... + + Run COMMAND in a different set of namespaces. + + -t PID to take namespaces from (--target) + -F don't fork, even if -p is used (--no-fork) + + The namespaces to switch are: + + -i SysV IPC: message queues, semaphores, shared memory (--ipc) + -m Mount/unmount tree (--mnt) + -n Network address, sockets, routing, iptables (--net) + -p Process IDs and init, will fork unless -F is used (--pid) + -u Host and domain names (--uts) + -U UIDs, GIDs, capabilities (--user) + + If -t isn't specified, each namespace argument must provide a path + to a namespace file, ala "-i=/proc/$PID/ns/ipc" +*/ + +#define FOR_nsenter +#include "toys.h" +#include +int unshare(int flags); +int setns(int fd, int nstype); + +GLOBALS( + char *nsnames[6]; + long targetpid; +) + +void unshare_main(void) +{ + unsigned flags[]={CLONE_NEWUSER, CLONE_NEWUTS, CLONE_NEWPID, CLONE_NEWNET, + CLONE_NEWNS, CLONE_NEWIPC}, f = 0; + int i, fd; + + // Create new namespace(s)? + if (CFG_UNSHARE && toys.which->name[0]) { + for (i = 0; i - -USE_UNSHARE(NEWTOY(unshare, "<1^imnpuU", TOYFLAG_USR|TOYFLAG_BIN)) - -config UNSHARE - bool "unshare" - default y - depends on TOYBOX_CONTAINER - help - usage: unshare [-imnpuU] COMMAND... - - Create new namespace(s) for this process and its children, so some - attribute is not shared with the parent process. This is part of - Linux Containers. Each process can have its own: - - -i SysV IPC (message queues, semaphores, shared memory) - -m Mount/unmount tree - -n Network address, sockets, routing, iptables - -p Process IDs and init - -u Host and domain names - -U UIDs, GIDs, capabilities -*/ - -#include "toys.h" -#include -extern int unshare (int __flags); - -void unshare_main(void) -{ - unsigned flags[]={CLONE_NEWUSER, CLONE_NEWUTS, CLONE_NEWPID, CLONE_NEWNET, - CLONE_NEWNS, CLONE_NEWIPC, 0}; - unsigned f=0; - int i; - - for (i=0; flags[i]; i++) if (toys.optflags & (1< - -USE_NSENTER(NEWTOY(nsenter, "<1F(no-fork)t#(target)i:(ipc);m:(mount);n:(net);p:(pid);u:(uts);U:(user);", TOYFLAG_USR|TOYFLAG_BIN)) - -config NSENTER - bool "nsenter" - default n - help - usage: nsenter [-t pid] [-F] [-i] [-m] [-n] [-p] [-u] [-U] COMMAND... - - Run COMMAND in a different set of namespaces. - - -T PID to take namespaces from - -F don't fork, even if -p is set - - The namespaces to switch are: - - -i SysV IPC (message queues, semaphores, shared memory) - -m Mount/unmount tree - -n Network address, sockets, routing, iptables - -p Process IDs and init (will fork unless -F is used) - -u Host and domain names - -U UIDs, GIDs, capabilities - - Each of those options takes an optional argument giving the path of - the namespace file (usually in /proc). This optional argument is - mandatory unless -t is used. -*/ - -#define FOR_nsenter -#define _GNU_SOURCE -#include "toys.h" -#include -#include -#include - -#define NUM_NSTYPES 6 - -struct nstype { - int type; - const char *name; -}; - -struct nstype nstypes[NUM_NSTYPES] = { - {CLONE_NEWUSER, "user"}, /* must be first to allow non-root operation */ - {CLONE_NEWUTS, "uts"}, - {CLONE_NEWPID, "pid"}, - {CLONE_NEWNET, "net"}, - {CLONE_NEWNS, "mnt"}, - {CLONE_NEWIPC, "ipc"}, -}; - -GLOBALS( - char *nsnames[6]; - long targetpid; -) - -static void enter_by_name(int idx) -{ - int fd, rc; - char buf[64]; - char *filename = TT.nsnames[idx]; - - if (!(toys.optflags & (1<