X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fvcontext.c;h=0d979cfa2ebd19a69f10472f6dc607a7487f5a2f;hb=b2210bdab172021023411c19353f5eaf4342c244;hp=a26b0c73695becfb4db9704561513cf545cf5979;hpb=089e32192c6700a566ab2abd1ac4a80c63d4d54e;p=util-vserver.git diff --git a/util-vserver/src/vcontext.c b/util-vserver/src/vcontext.c index a26b0c7..0d979cf 100644 --- a/util-vserver/src/vcontext.c +++ b/util-vserver/src/vcontext.c @@ -22,6 +22,7 @@ #include "util.h" #include "lib/internal.h" +#include "lib_internal/jail.h" #include #include @@ -29,6 +30,8 @@ #include #include #include +#include +#include #define ENSC_WRAPPERS_PREFIX "vcontext: " #define ENSC_WRAPPERS_UNISTD 1 @@ -43,14 +46,18 @@ #define CMD_XID 0x4000 #define CMD_CREATE 0x4001 #define CMD_MIGRATE 0x4003 -#define CMD_FAKEINIT 0x4002 +#define CMD_INITPID 0x4002 #define CMD_DISCONNECT 0x4004 #define CMD_UID 0x4005 #define CMD_CHROOT 0x4006 #define CMD_SILENT 0x4007 #define CMD_SYNCSOCK 0x4008 #define CMD_SYNCMSG 0x4009 -#define CMD_MIGRATESELF 0x4010 +#define CMD_MIGRATESELF 0x400a +#define CMD_ENDSETUP 0x400b +#define CMD_SILENTEXIST 0x400c +#define CMD_NAMESPACE 0x400d + struct option const CMDLINE_OPTIONS[] = { @@ -61,13 +68,19 @@ CMDLINE_OPTIONS[] = { { "create", no_argument, 0, CMD_CREATE }, { "migrate", no_argument, 0, CMD_MIGRATE }, { "migrate-self", no_argument, 0, CMD_MIGRATESELF }, - { "fakeinit", no_argument, 0, CMD_FAKEINIT }, + { "initpid", no_argument, 0, CMD_INITPID }, + { "endsetup", no_argument, 0, CMD_ENDSETUP }, { "disconnect", no_argument, 0, CMD_DISCONNECT }, { "silent", no_argument, 0, CMD_SILENT }, - { "uid", no_argument, 0, CMD_UID }, + { "silentexist", no_argument, 0, CMD_SILENTEXIST }, + { "uid", required_argument, 0, CMD_UID }, { "chroot", no_argument, 0, CMD_CHROOT }, + { "namespace", no_argument, 0, CMD_NAMESPACE }, { "syncsock", required_argument, 0, CMD_SYNCSOCK }, { "syncmsg", required_argument, 0, CMD_SYNCMSG }, +#if 1 + { "fakeinit", no_argument, 0, CMD_INITPID }, // compatibility +#endif { 0,0,0,0 }, }; @@ -76,7 +89,10 @@ struct Arguments { bool do_migrate; bool do_migrateself; bool do_disconnect; - bool is_fakeinit; + bool do_endsetup; + bool is_initpid; + bool is_silentexist; + bool set_namespace; int verbosity; bool do_chroot; uid_t uid; @@ -100,11 +116,15 @@ showHelp(int fd, char const *cmd, int res) "\n" " can be:\n" " --chroot ... chroot into current directory\n" + " --namespace ... execute namespace management operations\n" " --uid ... change uid\n" - " --fakeinit ... set current process as general process reaper\n" + " --initpid ... set current process as general process reaper\n" " for ctx (possible for --migrate only)\n" + " --endsetup ... clear the setup flag; usefully for migrate only\n" " --disconnect ... start program in background\n" " --silent ... be silent\n" + " --silentexist ... be silent when context exists already; usefully\n" + " for '--create' only\n" " --syncsock \n" " ... before executing the program, send a message\n" " to the socket and wait until it closes.\n" @@ -131,51 +151,7 @@ showVersion() exit(0); } -static inline ALWAYSINLINE int -initSync(int p[2], bool do_disconnect) -{ - if (!do_disconnect) return 0; - - Epipe(p); - fcntl(p[1], F_SETFD, FD_CLOEXEC); - return Efork(); -} - -static inline ALWAYSINLINE void -doSyncStage1(int p[2], bool do_disconnect) -{ - int fd; - - if (!do_disconnect) return; - - fd = Eopen("/dev/null", O_RDONLY, 0); - Esetsid(); - Edup2(fd, 0); - Eclose(p[0]); - if (fd!=0) Eclose(fd); - Ewrite(p[1], ".", 1); -} - -static inline ALWAYSINLINE void -doSyncStage2(int p[2], bool do_disconnect) -{ - if (!do_disconnect) return; - - Ewrite(p[1], "X", 1); -} - -static void -waitOnSync(pid_t pid, int p[2]) -{ - int c; - size_t l; - - Eclose(p[1]); - l = Eread(p[0], &c, 1); - if (l!=1) exitLikeProcess(pid); - l = Eread(p[0], &c, 1); - if (l!=0) exitLikeProcess(pid); -} +#include "context-sync.hc" static inline ALWAYSINLINE void tellContext(xid_t ctx, bool do_it) @@ -187,9 +163,9 @@ tellContext(xid_t ctx, bool do_it) l = utilvserver_fmt_long(buf,ctx); - WRITE_MSG(2, "New security context is "); - write(2, buf, l); - WRITE_MSG(2, "\n"); + WRITE_MSG(1, "New security context is "); + write(1, buf, l); + WRITE_MSG(1, "\n"); } static int @@ -209,6 +185,23 @@ connectExternalSync(char const *filename) } static void +setFlags(struct Arguments const *args, xid_t xid) +{ + struct vc_ctx_flags flags = { 0,0 }; + + if (args->is_initpid) + flags.mask |= VC_VXF_STATE_INIT; + + if (args->do_endsetup) + flags.mask |= VC_VXF_STATE_SETUP; + + if (flags.mask!=0) { + DPRINTF("set_flags: mask=%08llx, flag=%08llx\n", flags.mask, flags.flagword); + Evc_set_cflags(xid, &flags); + } +} + +static void doExternalSync(int fd, char const *msg) { char c; @@ -219,7 +212,7 @@ doExternalSync(int fd, char const *msg) Eshutdown(fd, SHUT_WR); if (TEMP_FAILURE_RETRY(recv(fd, &c, 1, MSG_NOSIGNAL))!=0) { - WRITE_MSG(2, "vcontext: unexpected external synchronization event\n"); + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "unexpected external synchronization event\n"); exit(255); } @@ -229,20 +222,26 @@ doExternalSync(int fd, char const *msg) static inline ALWAYSINLINE int doit(struct Arguments const *args, char *argv[]) { - int p[2]; + int p[2][2]; pid_t pid = initSync(p, args->do_disconnect); if (pid==0) { - xid_t xid; - int ext_sync_fd = connectExternalSync(args->sync_sock); + xid_t xid; + int ext_sync_fd = connectExternalSync(args->sync_sock); + + doSyncStage0(p, args->do_disconnect); if (args->do_create) { - xid = vc_create_context(args->xid); + xid = vc_ctx_create(args->xid); if (xid==VC_NOCTX) { - if (errno==EEXIST) return 254; - else { - perror(ENSC_WRAPPERS_PREFIX "vc_create_context()"); - return wrapper_exit_code; + switch (errno) { + case EEXIST : + if (!args->is_silentexist) + perror(ENSC_WRAPPERS_PREFIX "vc_create_context()"); + return 254; + default : + perror(ENSC_WRAPPERS_PREFIX "vc_create_context()"); + return wrapper_exit_code; } } tellContext(xid, args->verbosity>=1); @@ -250,46 +249,40 @@ doit(struct Arguments const *args, char *argv[]) else xid = args->xid; - if (args->do_chroot) + if (args->do_chroot) { Echroot("."); + if (args->set_namespace) { + if (args->do_migrateself) Evc_set_namespace(); + else if (args->do_migrate) Evc_enter_namespace(xid); + } + } + + setFlags(args, xid); + + if (args->do_migrate && !args->do_migrateself) + Evc_ctx_migrate(xid); if (args->uid!=(uid_t)(-1) && getuid()!=args->uid) { Esetuid(args->uid); if (getuid()!=args->uid) { - WRITE_MSG(2, "vcontext: Something went wrong while changing the UID\n"); + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Something went wrong while changing the UID\n"); exit(255); } } - - if (args->is_fakeinit) { - struct vc_ctx_flags test_flags; - struct vc_ctx_flags flags = { - .flagword = S_CTX_INFO_INIT, - .mask = S_CTX_INFO_INIT - }; - - Evc_get_flags(xid, &test_flags); - if ((flags.mask & S_CTX_INFO_INIT)==0) { - WRITE_MSG(2, "vcontext: context has already a fakeinit-process\n"); - exit(255); - } - - Evc_set_flags(xid, &flags); - } - - if (args->do_migrate && !args->do_migrateself) - Evc_migrate_context(xid); - + doExternalSync(ext_sync_fd, args->sync_msg); doSyncStage1(p, args->do_disconnect); + DPRINTF("doit: pid=%u, ppid=%u\n", getpid(), getppid()); execvp (argv[optind],argv+optind); doSyncStage2(p, args->do_disconnect); - PERROR_Q("chcontext: execvp", argv[optind]); + PERROR_Q(ENSC_WRAPPERS_PREFIX "execvp", argv[optind]); exit(255); } - waitOnSync(pid, p); + assert(args->do_disconnect); + + waitOnSync(pid, p, args->xid!=VC_DYNAMIC_XID && args->do_migrate); return EXIT_SUCCESS; } @@ -300,7 +293,10 @@ int main (int argc, char *argv[]) .do_migrate = false, .do_migrateself = false, .do_disconnect = false, - .is_fakeinit = false, + .do_endsetup = false, + .is_initpid = false, + .is_silentexist = false, + .set_namespace = false, .verbosity = 1, .uid = -1, .xid = VC_DYNAMIC_XID, @@ -314,16 +310,19 @@ int main (int argc, char *argv[]) switch (c) { case CMD_HELP : showHelp(1, argv[0], 0); case CMD_VERSION : showVersion(); - case CMD_CREATE : args.do_create = true; break; - case CMD_MIGRATE : args.do_migrate = true; break; - case CMD_DISCONNECT : args.do_disconnect = true; break; - case CMD_FAKEINIT : args.is_fakeinit = true; break; - case CMD_CHROOT : args.do_chroot = true; break; - case CMD_SILENT : --args.verbosity; break; - case CMD_XID : args.xid = atol(optarg); break; - case CMD_UID : args.uid = atol(optarg); break; - case CMD_SYNCSOCK : args.sync_sock = optarg; break; - case CMD_SYNCMSG : args.sync_msg = optarg; break; + case CMD_CREATE : args.do_create = true; break; + case CMD_MIGRATE : args.do_migrate = true; break; + case CMD_DISCONNECT : args.do_disconnect = true; break; + case CMD_ENDSETUP : args.do_endsetup = true; break; + case CMD_INITPID : args.is_initpid = true; break; + case CMD_CHROOT : args.do_chroot = true; break; + case CMD_NAMESPACE : args.set_namespace = true; break; + case CMD_SILENTEXIST : args.is_silentexist = true; break; + case CMD_SYNCSOCK : args.sync_sock = optarg; break; + case CMD_SYNCMSG : args.sync_msg = optarg; break; + case CMD_UID : args.uid = atol(optarg); break; + case CMD_XID : args.xid = Evc_xidopt2xid(optarg,true); break; + case CMD_SILENT : --args.verbosity; break; case CMD_MIGRATESELF : args.do_migrate = true; args.do_migrateself = true; @@ -338,6 +337,8 @@ int main (int argc, char *argv[]) } } + signal(SIGCHLD, SIG_DFL); + if (args.do_migrateself) args.xid = Evc_get_task_xid(0); @@ -345,10 +346,10 @@ int main (int argc, char *argv[]) WRITE_MSG(2, "Neither '--create' nor '--migrate specified; try '--help' for more information\n"); else if (args.do_create && args.do_migrate) WRITE_MSG(2, "Can not specify '--create' and '--migrate' at the same time; try '--help' for more information\n"); - else if (!args.do_migrate && args.is_fakeinit) - WRITE_MSG(2, "'--fakeinit' is possible in combination with '--migrate' only\n"); + else if (!args.do_migrate && args.is_initpid) + WRITE_MSG(2, "'--initpid' is possible in combination with '--migrate' only\n"); else if (!args.do_create && args.xid==VC_DYNAMIC_XID) - WRITE_MSG(2, "vcontext: Can not migrate to an unknown context\n"); + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Can not migrate to an unknown context\n"); else if (optind>=argc) WRITE_MSG(2, "No command given; use '--help' for more information.\n"); else