lxc_attach.c revision e6cde7418c4e697876f0041b888766ab4732812b
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * lxc: linux Container library
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * (C) Copyright IBM Corp. 2007, 2010
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * Daniel Lezcano <dlezcano at fr.ibm.com>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * This library is free software; you can redistribute it and/or
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * modify it under the terms of the GNU Lesser General Public
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * License as published by the Free Software Foundation; either
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * version 2.1 of the License, or (at your option) any later version.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * This library is distributed in the hope that it will be useful,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * but WITHOUT ANY WARRANTY; without even the implied warranty of
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * Lesser General Public License for more details.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * You should have received a copy of the GNU Lesser General Public
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * License along with this library; if not, write to the Free Software
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber {"elevated-privileges", no_argument, 0, 'e'},
b85ab7989ebe24629267048cb269b278eeb50490Serge Hallynstatic int my_parser(struct lxc_arguments* args, int c, char* arg)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn switch (c) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn lxc_error(args, "invalid architecture specified: %s", arg);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_fill_namespace_flags(arg, &namespace_flags);
eee3ba81c88e64b8a732694fc4843a39d5bde491Serge Hallyn /* -s implies -e */
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn--name=NAME\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge HallynExecute the specified command - enter the container NAME\n\
bf7d76cf3ae180820c0a29e0bfbaa97c20ce6a3dSerge Hallyn -n, --name=NAME NAME for name of the container\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn -e, --elevated-privileges\n\
542939c31bb73bab55f2fd71243b98f5559597d1Stéphane Graber Use elevated privileges (capabilities, cgroup\n\
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn restrictions) instead of those of the container.\n\
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn WARNING: This may leak privleges into the container.\n\
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn Use with care.\n\
542939c31bb73bab55f2fd71243b98f5559597d1Stéphane Graber -a, --arch=ARCH Use ARCH for program instead of container's own\n\
542939c31bb73bab55f2fd71243b98f5559597d1Stéphane Graber architecture.\n\
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn -s, --namespaces=FLAGS\n\
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn Don't attach to all the namespaces of the container\n\
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn but just to the following OR'd list of flags:\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn MOUNT, PID, UTSNAME, IPC, USER or NETWORK\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn WARNING: Using -s implies -e, it may therefore\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn leak privileges into the container. Use with care.\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn -R, --remount-sys-proc\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn Remount /sys and /proc if not attaching to the\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn mount namespace when using -s in order to properly\n\
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn reflect the correct namespace context. See the\n\
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn lxc-attach(1) manual page for details.\n",
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_arguments_parse(&my_args, argc, argv);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_log_init(my_args.log_file, my_args.log_priority,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn init_ctx = lxc_proc_get_context_info(init_pid);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ERROR("failed to get context of the init process, pid = %d", init_pid);
ed4616b1cfbc84dd01caa8546d813e8c5d482921Christian Bühler /* we have to do this now since /sys/fs/cgroup may not
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * be available inside the container or we may not have
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * the required permissions anymore
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_cgroup_prepare_attach(my_args.name, &cgroup_data);
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn ERROR("failed to prepare attaching to cgroup");
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* determine which namespaces the container was created with
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn * by asking lxc-start
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn namespace_flags = lxc_get_clone_flags(my_args.name);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* call failed */
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn "namespaces which the container unshared");
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn /* we need to attach before we fork since certain namespaces
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn * (such as pid namespaces) only really affect children of the
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn * current process and not the process itself
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn ret = lxc_attach_to_ns(init_pid, namespace_flags);
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn WARN("could not change directory to '%s'", curdir);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* hack: we need sync.h infrastructure - and that needs a handler */
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn ERROR("failed to initialize synchronization socket");
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber /* wait until the child has done configuring itself before
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber * we put it in a cgroup that potentially limits these
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber * possibilities */
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE))
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber /* now that we are done with all privileged operations,
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber * we can add ourselves to the cgroup. Since we smuggled in
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber * the fds earlier, we still have write permission
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber /* since setns() for pid namespaces only really
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * affects child processes, the pid we have is
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * still valid outside the container, so this is
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn ret = lxc_cgroup_finish_attach(cgroup_data, pid);
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn /* tell the child we are done initializing */
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn if (lxc_sync_wake_child(handler, LXC_SYNC_POST_CONFIGURE))
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* A description of the purpose of this functionality is
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn * provided in the lxc-attach(1) manual page. We have to
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn * remount here and not in the parent process, otherwise
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn * /proc may not properly reflect the new pid namespace.
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn if (!(namespace_flags & CLONE_NEWNS) && remount_sys_proc) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ERROR("could not ensure correct architecture: %s",
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser if (!elevated_privileges && lxc_attach_drop_privs(init_ctx)) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* tell parent we are done setting up the container and wait
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn * until we have been put in the container's cgroup, if
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn * applicable */
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE))
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn SYSERROR("failed to exec '%s'", my_args.argv[0]);
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn char *const args[] = {