~serge-hallyn/ubuntu/quantal/lxc/lxc-user-ns

« back to all changes in this revision

Viewing changes to .pc/lxc-use-user-namespace.patch/src/lxc/start.c

  • Committer: Serge Hallyn
  • Date: 2012-10-29 16:51:57 UTC
  • Revision ID: serge.hallyn@ubuntu.com-20121029165157-xw2nxym7eo0ocxu4
Add user namespaces patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lxc: linux Container library
 
3
 *
 
4
 * (C) Copyright IBM Corp. 2007, 2008
 
5
 *
 
6
 * Authors:
 
7
 * Daniel Lezcano <dlezcano at fr.ibm.com>
 
8
 *
 
9
 * This library is free software; you can redistribute it and/or
 
10
 * modify it under the terms of the GNU Lesser General Public
 
11
 * License as published by the Free Software Foundation; either
 
12
 * version 2.1 of the License, or (at your option) any later version.
 
13
 *
 
14
 * This library is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
 * Lesser General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU Lesser General Public
 
20
 * License along with this library; if not, write to the Free Software
 
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
22
 */
 
23
 
 
24
#include "config.h"
 
25
 
 
26
#include <stdio.h>
 
27
#undef _GNU_SOURCE
 
28
#include <string.h>
 
29
#include <stdlib.h>
 
30
#include <dirent.h>
 
31
#include <errno.h>
 
32
#include <unistd.h>
 
33
#include <signal.h>
 
34
#include <fcntl.h>
 
35
#include <termios.h>
 
36
#include <sys/param.h>
 
37
#include <sys/file.h>
 
38
#include <sys/mount.h>
 
39
#include <sys/stat.h>
 
40
#include <sys/types.h>
 
41
#include <sys/prctl.h>
 
42
#include <sys/types.h>
 
43
#include <sys/capability.h>
 
44
#include <sys/wait.h>
 
45
#include <sys/un.h>
 
46
#include <sys/poll.h>
 
47
#include <sys/apparmor.h>
 
48
 
 
49
int apparmor_enabled = 0;
 
50
 
 
51
#ifdef HAVE_SYS_SIGNALFD_H
 
52
#  include <sys/signalfd.h>
 
53
#else
 
54
/* assume kernel headers are too old */
 
55
#include <stdint.h>
 
56
struct signalfd_siginfo
 
57
{
 
58
        uint32_t ssi_signo;
 
59
        int32_t ssi_errno;
 
60
        int32_t ssi_code;
 
61
        uint32_t ssi_pid;
 
62
        uint32_t ssi_uid;
 
63
        int32_t ssi_fd;
 
64
        uint32_t ssi_tid;
 
65
        uint32_t ssi_band;
 
66
        uint32_t ssi_overrun;
 
67
        uint32_t ssi_trapno;
 
68
        int32_t ssi_status;
 
69
        int32_t ssi_int;
 
70
        uint64_t ssi_ptr;
 
71
        uint64_t ssi_utime;
 
72
        uint64_t ssi_stime;
 
73
        uint64_t ssi_addr;
 
74
        uint8_t __pad[48];
 
75
};
 
76
 
 
77
#  ifndef __NR_signalfd4
 
78
/* assume kernel headers are too old */
 
79
#    if __i386__
 
80
#      define __NR_signalfd4 327
 
81
#    elif __x86_64__
 
82
#      define __NR_signalfd4 289
 
83
#    elif __powerpc__
 
84
#      define __NR_signalfd4 313
 
85
#    elif __s390x__
 
86
#      define __NR_signalfd4 322
 
87
#    endif
 
88
#endif
 
89
 
 
90
#  ifndef __NR_signalfd
 
91
/* assume kernel headers are too old */
 
92
#    if __i386__
 
93
#      define __NR_signalfd 321
 
94
#    elif __x86_64__
 
95
#      define __NR_signalfd 282
 
96
#    elif __powerpc__
 
97
#      define __NR_signalfd 305
 
98
#    elif __s390x__
 
99
#      define __NR_signalfd 316
 
100
#    endif
 
101
#endif
 
102
 
 
103
int signalfd(int fd, const sigset_t *mask, int flags)
 
104
{
 
105
        int retval;
 
106
 
 
107
        retval = syscall (__NR_signalfd4, fd, mask, _NSIG / 8, flags);
 
108
        if (errno == ENOSYS && flags == 0)
 
109
                retval = syscall (__NR_signalfd, fd, mask, _NSIG / 8);
 
110
        return retval;
 
111
}
 
112
#endif
 
113
 
 
114
#if !HAVE_DECL_PR_CAPBSET_DROP
 
115
#define PR_CAPBSET_DROP 24
 
116
#endif
 
117
 
 
118
#include "start.h"
 
119
#include "conf.h"
 
120
#include "log.h"
 
121
#include "cgroup.h"
 
122
#include "error.h"
 
123
#include "af_unix.h"
 
124
#include "mainloop.h"
 
125
#include "utils.h"
 
126
#include "utmp.h"
 
127
#include "monitor.h"
 
128
#include "commands.h"
 
129
#include "console.h"
 
130
#include "sync.h"
 
131
#include "namespace.h"
 
132
#include "lxcseccomp.h"
 
133
 
 
134
lxc_log_define(lxc_start, lxc);
 
135
 
 
136
static int match_fd(int fd)
 
137
{
 
138
        return (fd == 0 || fd == 1 || fd == 2);
 
139
}
 
140
 
 
141
int lxc_check_inherited(struct lxc_conf *conf, int fd_to_ignore)
 
142
{
 
143
        struct dirent dirent, *direntp;
 
144
        int fd, fddir;
 
145
        DIR *dir;
 
146
 
 
147
restart:
 
148
        dir = opendir("/proc/self/fd");
 
149
        if (!dir) {
 
150
                WARN("failed to open directory: %m");
 
151
                return -1;
 
152
        }
 
153
 
 
154
        fddir = dirfd(dir);
 
155
 
 
156
        while (!readdir_r(dir, &dirent, &direntp)) {
 
157
                if (!direntp)
 
158
                        break;
 
159
 
 
160
                if (!strcmp(direntp->d_name, "."))
 
161
                        continue;
 
162
 
 
163
                if (!strcmp(direntp->d_name, ".."))
 
164
                        continue;
 
165
 
 
166
                fd = atoi(direntp->d_name);
 
167
 
 
168
                if (fd == fddir || fd == lxc_log_fd || fd == fd_to_ignore)
 
169
                        continue;
 
170
 
 
171
                if (match_fd(fd))
 
172
                        continue;
 
173
 
 
174
                if (conf->close_all_fds) {
 
175
                        close(fd);
 
176
                        closedir(dir);
 
177
                        INFO("closed inherited fd %d", fd);
 
178
                        goto restart;
 
179
                }
 
180
                WARN("inherited fd %d", fd);
 
181
        }
 
182
 
 
183
        closedir(dir); /* cannot fail */
 
184
        return 0;
 
185
}
 
186
 
 
187
static int setup_signal_fd(sigset_t *oldmask)
 
188
{
 
189
        sigset_t mask;
 
190
        int fd;
 
191
 
 
192
        /* Block everything except serious error signals */
 
193
        if (sigfillset(&mask) ||
 
194
            sigdelset(&mask, SIGILL) ||
 
195
            sigdelset(&mask, SIGSEGV) ||
 
196
            sigdelset(&mask, SIGBUS) ||
 
197
            sigprocmask(SIG_BLOCK, &mask, oldmask)) {
 
198
                SYSERROR("failed to set signal mask");
 
199
                return -1;
 
200
        }
 
201
 
 
202
        fd = signalfd(-1, &mask, 0);
 
203
        if (fd < 0) {
 
204
                SYSERROR("failed to create the signal fd");
 
205
                return -1;
 
206
        }
 
207
 
 
208
        if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
 
209
                SYSERROR("failed to set sigfd to close-on-exec");
 
210
                close(fd);
 
211
                return -1;
 
212
        }
 
213
 
 
214
        DEBUG("sigchild handler set");
 
215
 
 
216
        return fd;
 
217
}
 
218
 
 
219
static int signal_handler(int fd, void *data,
 
220
                           struct lxc_epoll_descr *descr)
 
221
{
 
222
        struct signalfd_siginfo siginfo;
 
223
        int ret;
 
224
        pid_t *pid = data;
 
225
 
 
226
        ret = read(fd, &siginfo, sizeof(siginfo));
 
227
        if (ret < 0) {
 
228
                ERROR("failed to read signal info");
 
229
                return -1;
 
230
        }
 
231
 
 
232
        if (ret != sizeof(siginfo)) {
 
233
                ERROR("unexpected siginfo size");
 
234
                return -1;
 
235
        }
 
236
 
 
237
        if (siginfo.ssi_signo != SIGCHLD) {
 
238
                kill(*pid, siginfo.ssi_signo);
 
239
                INFO("forwarded signal %d to pid %d", siginfo.ssi_signo, *pid);
 
240
                return 0;
 
241
        }
 
242
 
 
243
        if (siginfo.ssi_code == CLD_STOPPED ||
 
244
            siginfo.ssi_code == CLD_CONTINUED) {
 
245
                INFO("container init process was stopped/continued");
 
246
                return 0;
 
247
        }
 
248
 
 
249
        /* more robustness, protect ourself from a SIGCHLD sent
 
250
         * by a process different from the container init
 
251
         */
 
252
        if (siginfo.ssi_pid != *pid) {
 
253
                WARN("invalid pid for SIGCHLD");
 
254
                return 0;
 
255
        }
 
256
 
 
257
        DEBUG("container init process exited");
 
258
        return 1;
 
259
}
 
260
 
 
261
int lxc_pid_callback(int fd, struct lxc_request *request,
 
262
                     struct lxc_handler *handler)
 
263
{
 
264
        struct lxc_answer answer;
 
265
        int ret;
 
266
 
 
267
        answer.pid = handler->pid;
 
268
        answer.ret = 0;
 
269
 
 
270
        ret = send(fd, &answer, sizeof(answer), 0);
 
271
        if (ret < 0) {
 
272
                WARN("failed to send answer to the peer");
 
273
                return -1;
 
274
        }
 
275
 
 
276
        if (ret != sizeof(answer)) {
 
277
                ERROR("partial answer sent");
 
278
                return -1;
 
279
        }
 
280
 
 
281
        return 0;
 
282
}
 
283
 
 
284
int lxc_set_state(const char *name, struct lxc_handler *handler, lxc_state_t state)
 
285
{
 
286
        handler->state = state;
 
287
        lxc_monitor_send_state(name, state);
 
288
        return 0;
 
289
}
 
290
 
 
291
int lxc_poll(const char *name, struct lxc_handler *handler)
 
292
{
 
293
        int sigfd = handler->sigfd;
 
294
        int pid = handler->pid;
 
295
        struct lxc_epoll_descr descr;
 
296
 
 
297
        if (lxc_mainloop_open(&descr)) {
 
298
                ERROR("failed to create mainloop");
 
299
                goto out_sigfd;
 
300
        }
 
301
 
 
302
        if (lxc_mainloop_add_handler(&descr, sigfd, signal_handler, &pid)) {
 
303
                ERROR("failed to add handler for the signal");
 
304
                goto out_mainloop_open;
 
305
        }
 
306
 
 
307
        if (lxc_console_mainloop_add(&descr, handler)) {
 
308
                ERROR("failed to add console handler to mainloop");
 
309
                goto out_mainloop_open;
 
310
        }
 
311
 
 
312
        if (lxc_command_mainloop_add(name, &descr, handler)) {
 
313
                ERROR("failed to add command handler to mainloop");
 
314
                goto out_mainloop_open;
 
315
        }
 
316
 
 
317
        if (handler->conf->need_utmp_watch) {
 
318
                if (lxc_utmp_mainloop_add(&descr, handler)) {
 
319
                        ERROR("failed to add utmp handler to mainloop");
 
320
                        goto out_mainloop_open;
 
321
                }
 
322
        }
 
323
 
 
324
        return lxc_mainloop(&descr);
 
325
 
 
326
out_mainloop_open:
 
327
        lxc_mainloop_close(&descr);
 
328
out_sigfd:
 
329
        close(sigfd);
 
330
        return -1;
 
331
}
 
332
 
 
333
extern int lxc_caps_check(void);
 
334
 
 
335
struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf)
 
336
{
 
337
        struct lxc_handler *handler;
 
338
 
 
339
        if (!lxc_caps_check()) {
 
340
                ERROR("Not running with sufficient privilege");
 
341
                return NULL;
 
342
        }
 
343
 
 
344
        handler = malloc(sizeof(*handler));
 
345
        if (!handler)
 
346
                return NULL;
 
347
 
 
348
        memset(handler, 0, sizeof(*handler));
 
349
 
 
350
        handler->conf = conf;
 
351
 
 
352
        handler->name = strdup(name);
 
353
        if (!handler->name) {
 
354
                ERROR("failed to allocate memory");
 
355
                goto out_free;
 
356
        }
 
357
 
 
358
        if (lxc_read_seccomp_config(conf) != 0) {
 
359
                ERROR("failed loading seccomp policy");
 
360
                goto out_free_name;
 
361
        }
 
362
 
 
363
        /* Begin the set the state to STARTING*/
 
364
        if (lxc_set_state(name, handler, STARTING)) {
 
365
                ERROR("failed to set state '%s'", lxc_state2str(STARTING));
 
366
                goto out_free_name;
 
367
        }
 
368
 
 
369
        if (run_lxc_hooks(name, "pre-start", conf)) {
 
370
                ERROR("failed to run pre-start hooks for container '%s'.", name);
 
371
                goto out_aborting;
 
372
        }
 
373
 
 
374
        if (lxc_create_tty(name, conf)) {
 
375
                ERROR("failed to create the ttys");
 
376
                goto out_aborting;
 
377
        }
 
378
 
 
379
        if (lxc_create_console(conf)) {
 
380
                ERROR("failed to create console");
 
381
                goto out_delete_tty;
 
382
        }
 
383
 
 
384
        /* the signal fd has to be created before forking otherwise
 
385
         * if the child process exits before we setup the signal fd,
 
386
         * the event will be lost and the command will be stuck */
 
387
        handler->sigfd = setup_signal_fd(&handler->oldmask);
 
388
        if (handler->sigfd < 0) {
 
389
                ERROR("failed to set sigchild fd handler");
 
390
                goto out_delete_console;
 
391
        }
 
392
 
 
393
        INFO("'%s' is initialized", name);
 
394
        return handler;
 
395
 
 
396
out_delete_console:
 
397
        lxc_delete_console(&conf->console);
 
398
out_delete_tty:
 
399
        lxc_delete_tty(&conf->tty_info);
 
400
out_aborting:
 
401
        lxc_set_state(name, handler, ABORTING);
 
402
out_free_name:
 
403
        free(handler->name);
 
404
        handler->name = NULL;
 
405
out_free:
 
406
        free(handler);
 
407
        return NULL;
 
408
}
 
409
 
 
410
void lxc_fini(const char *name, struct lxc_handler *handler)
 
411
{
 
412
        /* The STOPPING state is there for future cleanup code
 
413
         * which can take awhile
 
414
         */
 
415
        lxc_set_state(name, handler, STOPPING);
 
416
        lxc_set_state(name, handler, STOPPED);
 
417
 
 
418
        if (run_lxc_hooks(name, "post-stop", handler->conf))
 
419
                ERROR("failed to run post-stop hooks for container '%s'.", name);
 
420
 
 
421
        /* reset mask set by setup_signal_fd */
 
422
        if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
 
423
                WARN("failed to restore sigprocmask");
 
424
 
 
425
        lxc_delete_console(&handler->conf->console);
 
426
        lxc_delete_tty(&handler->conf->tty_info);
 
427
        free(handler->name);
 
428
        free(handler);
 
429
}
 
430
 
 
431
void lxc_abort(const char *name, struct lxc_handler *handler)
 
432
{
 
433
        lxc_set_state(name, handler, ABORTING);
 
434
        if (handler->pid > 0)
 
435
                kill(handler->pid, SIGKILL);
 
436
}
 
437
 
 
438
#include <sys/reboot.h>
 
439
#include <linux/reboot.h>
 
440
 
 
441
/*
 
442
 * reboot(LINUX_REBOOT_CMD_CAD_ON) will return -EINVAL
 
443
 * in a child pid namespace if container reboot support exists.
 
444
 * Otherwise, it will either succeed or return -EPERM.
 
445
 */
 
446
static int container_reboot_supported(void *arg)
 
447
{
 
448
        int *cmd = arg;
 
449
        int ret;
 
450
 
 
451
        ret = reboot(*cmd);
 
452
        if (ret == -1 && errno == EINVAL)
 
453
                return 1;
 
454
        return 0;
 
455
}
 
456
 
 
457
static int must_drop_cap_sys_boot(void)
 
458
{
 
459
        FILE *f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
 
460
        int ret, cmd, v;
 
461
        long stack_size = 4096;
 
462
        void *stack = alloca(stack_size) + stack_size;
 
463
        int status;
 
464
        pid_t pid;
 
465
 
 
466
        if (!f) {
 
467
                DEBUG("failed to open /proc/sys/kernel/ctrl-alt-del");
 
468
                return 1;
 
469
        }
 
470
 
 
471
        ret = fscanf(f, "%d", &v);
 
472
        fclose(f);
 
473
        if (ret != 1) {
 
474
                DEBUG("Failed to read /proc/sys/kernel/ctrl-alt-del");
 
475
                return 1;
 
476
        }
 
477
        cmd = v ? LINUX_REBOOT_CMD_CAD_ON : LINUX_REBOOT_CMD_CAD_OFF;
 
478
 
 
479
        pid = clone(container_reboot_supported, stack, CLONE_NEWPID | SIGCHLD, &cmd);
 
480
        if (pid < 0) {
 
481
                SYSERROR("failed to clone\n");
 
482
                return -1;
 
483
        }
 
484
        if (wait(&status) < 0) {
 
485
                SYSERROR("unexpected wait error: %m");
 
486
                return -1;
 
487
        }
 
488
 
 
489
        if (WEXITSTATUS(status) != 1)
 
490
                return 1;
 
491
 
 
492
        return 0;
 
493
}
 
494
 
 
495
#if 0
 
496
/* aa_getcon is not working right now.  Use our hand-rolled version below */
 
497
static int aa_am_unconfined(void)
 
498
{
 
499
        char *con;
 
500
        int ret = 0;
 
501
        if (aa_getcon(&con, NULL) == 0 && strcmp(con, "unconfined") == 0)
 
502
                ret = 1;
 
503
        free(con);
 
504
        return ret;
 
505
}
 
506
#else
 
507
static int aa_am_unconfined(void)
 
508
{
 
509
        int ret;
 
510
        char path[100], p[100];
 
511
        sprintf(path, "/proc/%d/attr/current", getpid());
 
512
        FILE *f = fopen(path, "r");
 
513
        if (!f)
 
514
                return 0;
 
515
        ret = fscanf(f, "%99s", p);
 
516
        fclose(f);
 
517
        if (ret < 1)
 
518
                return 0;
 
519
        if (strcmp(p, "unconfined") == 0)
 
520
                return 1;
 
521
        return 0;
 
522
}
 
523
#endif
 
524
 
 
525
#define AA_DEF_PROFILE "lxc-container-default"
 
526
static int apparmor_load(struct lxc_handler *handler)
 
527
{
 
528
        if (!apparmor_enabled) {
 
529
                INFO("apparmor not enabled");
 
530
                return 0;
 
531
        }
 
532
 
 
533
        if (!handler->conf->aa_profile)
 
534
                handler->conf->aa_profile = AA_DEF_PROFILE;
 
535
 
 
536
        if (strcmp(handler->conf->aa_profile, "unconfined") == 0 &&
 
537
            aa_am_unconfined()) {
 
538
                INFO("apparmor profile unchanged");
 
539
                return 0;
 
540
        }
 
541
 
 
542
        //if (aa_change_onexec(handler->conf->aa_profile) < 0) {
 
543
        if (aa_change_profile(handler->conf->aa_profile) < 0) {
 
544
                SYSERROR("failed to change apparmor profile to %s", handler->conf->aa_profile);
 
545
                return -1;
 
546
        }
 
547
        if (handler->conf->umount_proc == 1)
 
548
                umount("/proc");
 
549
 
 
550
        INFO("changed apparmor profile to %s", handler->conf->aa_profile);
 
551
 
 
552
        return 0;
 
553
}
 
554
 
 
555
static int do_start(void *data)
 
556
{
 
557
        struct lxc_handler *handler = data;
 
558
 
 
559
        if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) {
 
560
                SYSERROR("failed to set sigprocmask");
 
561
                return -1;
 
562
        }
 
563
 
 
564
        /* This prctl must be before the synchro, so if the parent
 
565
         * dies before we set the parent death signal, we will detect
 
566
         * its death with the synchro right after, otherwise we have
 
567
         * a window where the parent can exit before we set the pdeath
 
568
         * signal leading to a unsupervized container.
 
569
         */
 
570
        if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
 
571
                SYSERROR("failed to set pdeath signal");
 
572
                return -1;
 
573
        }
 
574
 
 
575
        lxc_sync_fini_parent(handler);
 
576
 
 
577
        /* Tell the parent task it can begin to configure the
 
578
         * container and wait for it to finish
 
579
         */
 
580
        if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE))
 
581
                return -1;
 
582
 
 
583
        if (handler->conf->need_utmp_watch) {
 
584
                if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) {
 
585
                        SYSERROR("failed to remove CAP_SYS_BOOT capability");
 
586
                        goto out_warn_father;
 
587
                }
 
588
                DEBUG("Dropped cap_sys_boot\n");
 
589
        }
 
590
 
 
591
        /* Setup the container, ip, names, utsname, ... */
 
592
        if (lxc_setup(handler->name, handler->conf)) {
 
593
                ERROR("failed to setup the container");
 
594
                goto out_warn_father;
 
595
        }
 
596
 
 
597
        if (apparmor_load(handler) < 0)
 
598
                goto out_warn_father;
 
599
 
 
600
        if (lxc_seccomp_load(handler->conf) != 0)
 
601
                goto out_warn_father;
 
602
 
 
603
        if (run_lxc_hooks(handler->name, "start", handler->conf)) {
 
604
                ERROR("failed to run start hooks for container '%s'.", handler->name);
 
605
                goto out_warn_father;
 
606
        }
 
607
 
 
608
        close(handler->sigfd);
 
609
 
 
610
        /* after this call, we are in error because this
 
611
         * ops should not return as it execs */
 
612
        if (handler->ops->start(handler, handler->data))
 
613
                return -1;
 
614
 
 
615
out_warn_father:
 
616
        lxc_sync_wake_parent(handler, LXC_SYNC_POST_CONFIGURE);
 
617
        return -1;
 
618
}
 
619
 
 
620
int lxc_spawn(struct lxc_handler *handler)
 
621
{
 
622
        int clone_flags;
 
623
        int failed_before_rename = 0;
 
624
        const char *name = handler->name;
 
625
        int pinfd;
 
626
 
 
627
        if (lxc_sync_init(handler))
 
628
                return -1;
 
629
 
 
630
        clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
 
631
        if (!lxc_list_empty(&handler->conf->network)) {
 
632
 
 
633
                clone_flags |= CLONE_NEWNET;
 
634
 
 
635
                /* Find gateway addresses from the link device, which is
 
636
                 * no longer accessible inside the container. Do this
 
637
                 * before creating network interfaces, since goto
 
638
                 * out_delete_net does not work before lxc_clone. */
 
639
                if (lxc_find_gateway_addresses(handler)) {
 
640
                        ERROR("failed to find gateway addresses");
 
641
                        lxc_sync_fini(handler);
 
642
                        return -1;
 
643
                }
 
644
 
 
645
                /* that should be done before the clone because we will
 
646
                 * fill the netdev index and use them in the child
 
647
                 */
 
648
                if (lxc_create_network(handler)) {
 
649
                        ERROR("failed to create the network");
 
650
                        lxc_sync_fini(handler);
 
651
                        return -1;
 
652
                }
 
653
        }
 
654
 
 
655
        /*
 
656
         * if the rootfs is not a blockdev, prevent the container from
 
657
         * marking it readonly.
 
658
         */
 
659
 
 
660
        pinfd = pin_rootfs(handler->conf->rootfs.path);
 
661
        if (pinfd == -1) {
 
662
                ERROR("failed to pin the container's rootfs");
 
663
                goto out_abort;
 
664
        }
 
665
 
 
666
        /* Create a process in a new set of namespaces */
 
667
        handler->pid = lxc_clone(do_start, handler, clone_flags);
 
668
        if (handler->pid < 0) {
 
669
                SYSERROR("failed to fork into a new namespace");
 
670
                goto out_delete_net;
 
671
        }
 
672
 
 
673
        lxc_sync_fini_child(handler);
 
674
 
 
675
        if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE))
 
676
                failed_before_rename = 1;
 
677
 
 
678
        if (lxc_cgroup_create(name, handler->pid))
 
679
                goto out_delete_net;
 
680
 
 
681
        if (failed_before_rename)
 
682
                goto out_delete_net;
 
683
 
 
684
        /* Create the network configuration */
 
685
        if (clone_flags & CLONE_NEWNET) {
 
686
                if (lxc_assign_network(&handler->conf->network, handler->pid)) {
 
687
                        ERROR("failed to create the configured network");
 
688
                        goto out_delete_net;
 
689
                }
 
690
        }
 
691
 
 
692
        /* Tell the child to continue its initialization and wait for
 
693
         * it to exec or return an error
 
694
         */
 
695
        if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE))
 
696
                return -1;
 
697
 
 
698
        if (handler->ops->post_start(handler, handler->data))
 
699
                goto out_abort;
 
700
 
 
701
        if (lxc_set_state(name, handler, RUNNING)) {
 
702
                ERROR("failed to set state to %s",
 
703
                              lxc_state2str(RUNNING));
 
704
                goto out_abort;
 
705
        }
 
706
 
 
707
        lxc_sync_fini(handler);
 
708
 
 
709
        if (pinfd >= 0)
 
710
                close(pinfd);
 
711
 
 
712
        return 0;
 
713
 
 
714
out_delete_net:
 
715
        if (clone_flags & CLONE_NEWNET)
 
716
                lxc_delete_network(&handler->conf->network);
 
717
out_abort:
 
718
        lxc_abort(name, handler);
 
719
        lxc_sync_fini(handler);
 
720
        return -1;
 
721
}
 
722
 
 
723
#define AA_MOUNT_RESTR "/sys/kernel/security/apparmor/features/mount/mask"
 
724
#define AA_ENABLED_FILE "/sys/module/apparmor/parameters/enabled"
 
725
static int check_apparmor_enabled(void)
 
726
{
 
727
        struct stat statbuf;
 
728
        FILE *fin;
 
729
        char e;
 
730
        int ret;
 
731
 
 
732
        ret = stat(AA_MOUNT_RESTR, &statbuf);
 
733
        if (ret != 0)
 
734
                return 0;
 
735
        fin = fopen(AA_ENABLED_FILE, "r");
 
736
        if (!fin)
 
737
                return 0;
 
738
        ret = fscanf(fin, "%c", &e);
 
739
        fclose(fin);
 
740
        if (ret == 1 && e == 'Y')
 
741
                return 1;
 
742
        return 0;
 
743
}
 
744
 
 
745
int __lxc_start(const char *name, struct lxc_conf *conf,
 
746
                struct lxc_operations* ops, void *data)
 
747
{
 
748
        struct lxc_handler *handler;
 
749
        int err = -1;
 
750
        int status;
 
751
 
 
752
        apparmor_enabled = check_apparmor_enabled();
 
753
 
 
754
        handler = lxc_init(name, conf);
 
755
        if (!handler) {
 
756
                ERROR("failed to initialize the container");
 
757
                return -1;
 
758
        }
 
759
        handler->ops = ops;
 
760
        handler->data = data;
 
761
 
 
762
        if (must_drop_cap_sys_boot()) {
 
763
                handler->conf->need_utmp_watch = 1;
 
764
                DEBUG("Dropping cap_sys_boot and watching utmp\n");
 
765
        } else {
 
766
                DEBUG("Not dropping cap_sys_boot or watching utmp\n");
 
767
                handler->conf->need_utmp_watch = 0;
 
768
        }
 
769
 
 
770
        err = lxc_spawn(handler);
 
771
        if (err) {
 
772
                ERROR("failed to spawn '%s'", name);
 
773
                goto out_fini;
 
774
        }
 
775
 
 
776
        err = lxc_poll(name, handler);
 
777
        if (err) {
 
778
                ERROR("mainloop exited with an error");
 
779
                goto out_abort;
 
780
        }
 
781
 
 
782
        while (waitpid(handler->pid, &status, 0) < 0 && errno == EINTR)
 
783
                continue;
 
784
 
 
785
        /*
 
786
         * If the child process exited but was not signaled,
 
787
         * it didn't call reboot.  This should mean it was an
 
788
         * lxc-execute which simply exited.  In any case, treat
 
789
         * it as a 'halt'
 
790
         */
 
791
        if (WIFSIGNALED(status)) {
 
792
                switch(WTERMSIG(status)) {
 
793
                case SIGINT: /* halt */
 
794
                        DEBUG("Container halting");
 
795
                        break;
 
796
                case SIGHUP: /* reboot */
 
797
                        DEBUG("Container rebooting");
 
798
                        handler->conf->reboot = 1;
 
799
                        break;
 
800
                default:
 
801
                        DEBUG("unknown exit status for init: %d\n", WTERMSIG(status));
 
802
                        break;
 
803
                }
 
804
        }
 
805
 
 
806
        err =  lxc_error_set_and_log(handler->pid, status);
 
807
out_fini:
 
808
        lxc_cgroup_destroy(name);
 
809
        lxc_fini(name, handler);
 
810
        return err;
 
811
 
 
812
out_abort:
 
813
        lxc_abort(name, handler);
 
814
        goto out_fini;
 
815
}
 
816
 
 
817
struct start_args {
 
818
        char *const *argv;
 
819
};
 
820
 
 
821
static int start(struct lxc_handler *handler, void* data)
 
822
{
 
823
        struct start_args *arg = data;
 
824
 
 
825
        NOTICE("exec'ing '%s'", arg->argv[0]);
 
826
 
 
827
        execvp(arg->argv[0], arg->argv);
 
828
        SYSERROR("failed to exec %s", arg->argv[0]);
 
829
        return 0;
 
830
}
 
831
 
 
832
static int post_start(struct lxc_handler *handler, void* data)
 
833
{
 
834
        struct start_args *arg = data;
 
835
 
 
836
        NOTICE("'%s' started with pid '%d'", arg->argv[0], handler->pid);
 
837
        return 0;
 
838
}
 
839
 
 
840
static struct lxc_operations start_ops = {
 
841
        .start = start,
 
842
        .post_start = post_start
 
843
};
 
844
 
 
845
int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
 
846
{
 
847
        struct start_args start_arg = {
 
848
                .argv = argv,
 
849
        };
 
850
 
 
851
        if (lxc_check_inherited(conf, -1))
 
852
                return -1;
 
853
 
 
854
        conf->need_utmp_watch = 1;
 
855
        return __lxc_start(name, conf, &start_ops, &start_arg);
 
856
}