X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fvcontext.c;h=ea107d50b57be9fea54c30b402c0c33699e8f959;hb=a917f24ef7b003dcef54a3db2644cf9cb4bc2db2;hp=337bdf407724f7f27daed911e6fbfc8b954e9793;hpb=1151f3f94da83c751aadd4b18e3d96791842e3f3;p=util-vserver.git diff --git a/util-vserver/src/vcontext.c b/util-vserver/src/vcontext.c index 337bdf4..ea107d5 100644 --- a/util-vserver/src/vcontext.c +++ b/util-vserver/src/vcontext.c @@ -22,6 +22,9 @@ #include "util.h" #include "lib/internal.h" +#include "lib_internal/jail.h" + +#include "linuxcaps.h" #include #include @@ -29,6 +32,7 @@ #include #include #include +#include #define ENSC_WRAPPERS_PREFIX "vcontext: " #define ENSC_WRAPPERS_UNISTD 1 @@ -50,6 +54,9 @@ #define CMD_SILENT 0x4007 #define CMD_SYNCSOCK 0x4008 #define CMD_SYNCMSG 0x4009 +#define CMD_MIGRATESELF 0x400a +#define CMD_ENDSETUP 0x400b +#define CMD_SILENTEXIST 0x400c struct option const CMDLINE_OPTIONS[] = { @@ -59,21 +66,27 @@ CMDLINE_OPTIONS[] = { { "xid", required_argument, 0, CMD_XID }, { "create", no_argument, 0, CMD_CREATE }, { "migrate", no_argument, 0, CMD_MIGRATE }, - { "fakeinit", no_argument, 0, CMD_FAKEINIT }, - { "disconnect", no_argument, 0, CMD_DISCONNECT }, - { "silent", no_argument, 0, CMD_SILENT }, - { "uid", no_argument, 0, CMD_UID }, - { "chroot", no_argument, 0, CMD_CHROOT }, - { "syncsock", required_argument, 0, CMD_SYNCSOCK }, - { "syncmsg", required_argument, 0, CMD_SYNCMSG }, + { "migrate-self", no_argument, 0, CMD_MIGRATESELF }, + { "fakeinit", no_argument, 0, CMD_FAKEINIT }, + { "endsetup", no_argument, 0, CMD_ENDSETUP }, + { "disconnect", no_argument, 0, CMD_DISCONNECT }, + { "silent", no_argument, 0, CMD_SILENT }, + { "silentexist", no_argument, 0, CMD_SILENTEXIST }, + { "uid", required_argument, 0, CMD_UID }, + { "chroot", no_argument, 0, CMD_CHROOT }, + { "syncsock", required_argument, 0, CMD_SYNCSOCK }, + { "syncmsg", required_argument, 0, CMD_SYNCMSG }, { 0,0,0,0 }, }; struct Arguments { bool do_create; bool do_migrate; + bool do_migrateself; bool do_disconnect; + bool do_endsetup; bool is_fakeinit; + bool is_silentexist; int verbosity; bool do_chroot; uid_t uid; @@ -93,15 +106,18 @@ showHelp(int fd, char const *cmd, int res) " --create [--xid ] * [--] *\n "); WRITE_STR(fd, cmd); WRITE_MSG(fd, - " --migrate --xid * [--] *\n" + " [(--migrate --xid )|--migrate-self] * [--] *\n" "\n" " can be:\n" " --chroot ... chroot into current directory\n" " --uid ... change uid\n" " --fakeinit ... 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" @@ -128,51 +144,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) @@ -184,9 +156,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 @@ -206,6 +178,21 @@ connectExternalSync(char const *filename) } static void +setFlags(struct Arguments const *args, xid_t xid) +{ + struct vc_ctx_flags flags = { 0,0 }; + + if (args->is_fakeinit) + flags.mask |= VC_VXF_STATE_INIT; + + if (args->do_endsetup) + flags.mask |= VC_VXF_STATE_SETUP; + + if (flags.mask!=0) + Evc_set_flags(xid, &flags); +} + +static void doExternalSync(int fd, char const *msg) { char c; @@ -216,7 +203,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); } @@ -226,20 +213,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); 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,57 +243,48 @@ doit(struct Arguments const *args, char *argv[]) if (args->do_chroot) Echroot("."); + setFlags(args, xid); + + if (args->do_migrate && !args->do_migrateself) + Evc_migrate_context(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"); - 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"); + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Something went wrong while changing the UID\n"); exit(255); } - - Evc_set_flags(xid, &flags); } - - if (args->do_migrate) - Evc_migrate_context(xid); - + doExternalSync(ext_sync_fd, args->sync_msg); doSyncStage1(p, args->do_disconnect); 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; } int main (int argc, char *argv[]) { struct Arguments args = { - .do_create = false, - .do_migrate = false, - .do_disconnect = false, - .is_fakeinit = false, - .verbosity = 1, - .uid = -1, - .xid = VC_DYNAMIC_XID, - .sync_msg = "ok", + .do_create = false, + .do_migrate = false, + .do_migrateself = false, + .do_disconnect = false, + .do_endsetup = false, + .is_fakeinit = false, + .is_silentexist = false, + .verbosity = 1, + .uid = -1, + .xid = VC_DYNAMIC_XID, + .sync_msg = "ok", }; while (1) { @@ -310,16 +294,22 @@ 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_FAKEINIT : args.is_fakeinit = true; break; + case CMD_CHROOT : args.do_chroot = 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; + break; default : WRITE_MSG(2, "Try '"); @@ -330,6 +320,9 @@ int main (int argc, char *argv[]) } } + if (args.do_migrateself) + args.xid = Evc_get_task_xid(0); + if (!args.do_create && !args.do_migrate) WRITE_MSG(2, "Neither '--create' nor '--migrate specified; try '--help' for more information\n"); else if (args.do_create && args.do_migrate) @@ -337,7 +330,7 @@ int main (int argc, char *argv[]) else if (!args.do_migrate && args.is_fakeinit) WRITE_MSG(2, "'--fakeinit' 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