lxc_attach.c revision e6cde7418c4e697876f0041b888766ab4732812b
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn/*
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * lxc: linux Container library
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn *
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * (C) Copyright IBM Corp. 2007, 2010
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn *
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * Authors:
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * Daniel Lezcano <dlezcano at fr.ibm.com>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn *
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 *
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 *
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
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn */
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#define _GNU_SOURCE
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include <unistd.h>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include <errno.h>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include <pwd.h>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include <stdlib.h>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include <sys/param.h>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include <sys/types.h>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include <sys/wait.h>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include "attach.h"
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn#include "commands.h"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include "arguments.h"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include "caps.h"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include "cgroup.h"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include "config.h"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#include "confile.h"
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn#include "start.h"
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn#include "sync.h"
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn#include "log.h"
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn#include "namespace.h"
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn#if HAVE_SYS_PERSONALITY_H
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn#include <sys/personality.h>
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn#endif
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graberlxc_log_define(lxc_attach_ui, lxc);
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynstatic const struct option my_longopts[] = {
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber {"elevated-privileges", no_argument, 0, 'e'},
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn {"arch", required_argument, 0, 'a'},
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn {"namespaces", required_argument, 0, 's'},
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber {"remount-sys-proc", no_argument, 0, 'R'},
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber LXC_COMMON_OPTIONS
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn};
eee3ba81c88e64b8a732694fc4843a39d5bde491Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynstatic int elevated_privileges = 0;
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graberstatic signed long new_personality = -1;
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graberstatic int namespace_flags = -1;
9313e1e628160ca64f9e7fcec6500056c9a0725fStéphane Graberstatic int remount_sys_proc = 0;
b85ab7989ebe24629267048cb269b278eeb50490Serge Hallyn
b85ab7989ebe24629267048cb269b278eeb50490Serge Hallynstatic int my_parser(struct lxc_arguments* args, int c, char* arg)
b85ab7989ebe24629267048cb269b278eeb50490Serge Hallyn{
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graber int ret;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn switch (c) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn case 'e': elevated_privileges = 1; break;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn case 'R': remount_sys_proc = 1; break;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn case 'a':
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn new_personality = lxc_config_parse_arch(arg);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (new_personality < 0) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn lxc_error(args, "invalid architecture specified: %s", arg);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn break;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn case 's':
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn namespace_flags = 0;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_fill_namespace_flags(arg, &namespace_flags);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (ret)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
eee3ba81c88e64b8a732694fc4843a39d5bde491Serge Hallyn /* -s implies -e */
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber elevated_privileges = 1;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn break;
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber return 0;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn}
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynstatic struct lxc_arguments my_args = {
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber .progname = "lxc-attach",
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn .help = "\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn--name=NAME\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn\n\
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge HallynExecute the specified command - enter the container NAME\n\
80a881b232b8955b85b360d4def99e6e680ff61bSerge Hallyn\n\
80a881b232b8955b85b360d4def99e6e680ff61bSerge HallynOptions :\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",
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn .options = my_longopts,
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn .parser = my_parser,
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn .checker = NULL,
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn};
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
4759162d078d86628956cae4846c6efccf548e67Serge Hallynint main(int argc, char *argv[])
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn{
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn int ret;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn pid_t pid, init_pid;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn struct passwd *passwd;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn struct lxc_proc_context_info *init_ctx;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn struct lxc_handler *handler;
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn void *cgroup_data = NULL;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn uid_t uid;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn char *curdir;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_caps_init();
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (ret)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return ret;
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_arguments_parse(&my_args, argc, argv);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (ret)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return ret;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_log_init(my_args.log_file, my_args.log_priority,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn my_args.progname, my_args.quiet);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (ret)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return ret;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn init_pid = get_init_pid(my_args.name);
f34ff296835b2afa4b80018651d902448c99ac75Serge Hallyn if (init_pid < 0) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ERROR("failed to get the init pid");
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn init_ctx = lxc_proc_get_context_info(init_pid);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (!init_ctx) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ERROR("failed to get context of the init process, pid = %d", init_pid);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (!elevated_privileges) {
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 */
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = lxc_cgroup_prepare_attach(my_args.name, &cgroup_data);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (ret < 0) {
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn ERROR("failed to prepare attaching to cgroup");
b8bced69a80a8be95fdbbb6b4e9ad7fa85464b1eSerge Hallyn return -1;
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn }
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn }
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn curdir = getcwd(NULL, 0);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* determine which namespaces the container was created with
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn * by asking lxc-start
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn */
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (namespace_flags == -1) {
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn namespace_flags = lxc_get_clone_flags(my_args.name);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* call failed */
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn if (namespace_flags == -1) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ERROR("failed to automatically determine the "
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn "namespaces which the container unshared");
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn }
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn }
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
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 */
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn ret = lxc_attach_to_ns(init_pid, namespace_flags);
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn if (ret < 0) {
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn ERROR("failed to enter the namespace");
6b1a07ba086d16cfa822caadf95eab62b70889cdSerge Hallyn return -1;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn }
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn if (curdir && chdir(curdir))
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn WARN("could not change directory to '%s'", curdir);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn free(curdir);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* hack: we need sync.h infrastructure - and that needs a handler */
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn handler = calloc(1, sizeof(*handler));
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn if (lxc_sync_init(handler)) {
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn ERROR("failed to initialize synchronization socket");
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn pid = fork();
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber if (pid < 0) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn SYSERROR("failed to fork");
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn }
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber if (pid) {
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber int status;
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber lxc_sync_fini_child(handler);
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
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 return -1;
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
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 */
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber if (!elevated_privileges) {
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
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * fine
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn */
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn ret = lxc_cgroup_finish_attach(cgroup_data, pid);
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn if (ret < 0) {
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn ERROR("failed to attach process to cgroup");
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn return -1;
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn }
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn }
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn /* tell the child we are done initializing */
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn if (lxc_sync_wake_child(handler, LXC_SYNC_POST_CONFIGURE))
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn return -1;
10f73bfa4aece7707f48379b82e5858d1909d98fSerge Hallyn
5a0f7f3c707bf713f35382eaabc54395d2b36b12Serge Hallyn lxc_sync_fini(handler);
5a0f7f3c707bf713f35382eaabc54395d2b36b12Serge Hallyn
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser again:
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser if (waitpid(pid, &status, 0) < 0) {
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser if (errno == EINTR)
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser goto again;
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser SYSERROR("failed to wait '%d'", pid);
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser return -1;
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser }
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser if (WIFEXITED(status))
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return WEXITSTATUS(status);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (!pid) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn lxc_sync_fini_parent(handler);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn lxc_cgroup_dispose_attach(cgroup_data);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
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 */
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn if (!(namespace_flags & CLONE_NEWNS) && remount_sys_proc) {
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn ret = lxc_attach_remount_sys_proc();
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn if (ret < 0) {
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn return -1;
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn #if HAVE_SYS_PERSONALITY_H
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (new_personality < 0)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn new_personality = init_ctx->personality;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
e29bf450cafa2ce2564aeb0b64d2014c17228407Dwight Engen if (personality(new_personality) == -1) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ERROR("could not ensure correct architecture: %s",
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn strerror(errno));
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return -1;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn }
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser #endif
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser if (!elevated_privileges && lxc_attach_drop_privs(init_ctx)) {
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser ERROR("could not drop privileges");
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn return -1;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn }
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
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))
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn return -1;
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn lxc_sync_fini(handler);
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn if (my_args.argc) {
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn execvp(my_args.argv[0], my_args.argv);
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn SYSERROR("failed to exec '%s'", my_args.argv[0]);
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn return -1;
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn }
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn uid = getuid();
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn passwd = getpwuid(uid);
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn if (!passwd) {
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn SYSERROR("failed to get passwd " \
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn "entry for uid '%d'", uid);
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn return -1;
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn }
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
edd3810e951ec1b20af761955e6100ab75a66534Serge Hallyn {
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn char *const args[] = {
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn passwd->pw_shell,
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn NULL,
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn };
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn execvp(args[0], args);
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn SYSERROR("failed to exec '%s'", args[0]);
edd3810e951ec1b20af761955e6100ab75a66534Serge Hallyn return -1;
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn }
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn }
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn return 0;
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn}
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn