]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/attach.c
attach: simplify lsm_openat()
[mirror_lxc.git] / src / lxc / attach.c
CommitLineData
e0732705
CS
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
e0732705
CS
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
250b1eec 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e0732705
CS
22 */
23
24#define _GNU_SOURCE
25#include <unistd.h>
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
2eef2bda 29#include <signal.h>
e0732705
CS
30#include <errno.h>
31#include <fcntl.h>
c476bdce 32#include <grp.h>
e0732705
CS
33#include <sys/param.h>
34#include <sys/prctl.h>
7a0b0b56 35#include <sys/mount.h>
5ec27989 36#include <sys/socket.h>
1ba0013f 37#include <sys/syscall.h>
905022f7 38#include <sys/wait.h>
910bb4fa 39#include <linux/unistd.h>
905022f7 40#include <pwd.h>
e0732705 41
955e2a02 42#ifndef HAVE_DECL_PR_CAPBSET_DROP
e0732705
CS
43#define PR_CAPBSET_DROP 24
44#endif
45
955e2a02
CB
46#ifndef HAVE_DECL_PR_SET_NO_NEW_PRIVS
47#define PR_SET_NO_NEW_PRIVS 38
48#endif
49
50#ifndef HAVE_DECL_PR_GET_NO_NEW_PRIVS
51#define PR_GET_NO_NEW_PRIVS 39
52#endif
53
e0732705
CS
54#include "namespace.h"
55#include "log.h"
81f466d0 56#include "af_unix.h"
e0732705
CS
57#include "attach.h"
58#include "caps.h"
e0732705 59#include "config.h"
6a44839f 60#include "utils.h"
9c4693b8
CS
61#include "commands.h"
62#include "cgroup.h"
025ed0f3 63#include "lxclock.h"
2c4ea790
SH
64#include "conf.h"
65#include "lxcseccomp.h"
66#include <lxc/lxccontainer.h>
fe4de9a6 67#include "lsm/lsm.h"
9b8e3c96 68#include "confile.h"
9c4693b8
CS
69
70#if HAVE_SYS_PERSONALITY_H
71#include <sys/personality.h>
72#endif
e0732705 73
a3da2f3b
SG
74#ifndef SOCK_CLOEXEC
75# define SOCK_CLOEXEC 02000000
76#endif
77
d6a3c917
SG
78#ifndef MS_REC
79#define MS_REC 16384
80#endif
81
82#ifndef MS_SLAVE
83#define MS_SLAVE (1<<19)
84#endif
85
e0732705
CS
86lxc_log_define(lxc_attach, lxc);
87
82b1f317
CB
88/* /proc/pid-to-str/current\0 = (5 + 21 + 7 + 1) */
89#define __LSMATTRLEN (5 + 21 + 7 + 1)
81f466d0
CB
90static int lsm_openat(int procfd, pid_t pid, int on_exec)
91{
92 int ret = -1;
5c3fcae7 93 int labelfd = -1;
82b1f317 94 const char *name;
81f466d0 95 char path[__LSMATTRLEN];
5c3fcae7
SG
96
97 name = lsm_name();
98
99 if (strcmp(name, "nop") == 0)
81f466d0 100 return 0;
5c3fcae7
SG
101
102 if (strcmp(name, "none") == 0)
81f466d0 103 return 0;
5c3fcae7
SG
104
105 /* We don't support on-exec with AppArmor */
106 if (strcmp(name, "AppArmor") == 0)
107 on_exec = 0;
108
82b1f317 109 if (on_exec)
81f466d0 110 ret = snprintf(path, __LSMATTRLEN, "%d/attr/exec", pid);
82b1f317 111 else
81f466d0 112 ret = snprintf(path, __LSMATTRLEN, "%d/attr/current", pid);
82b1f317
CB
113 if (ret < 0 || ret >= __LSMATTRLEN)
114 return -1;
5c3fcae7 115
82b1f317 116 labelfd = openat(procfd, path, O_RDWR);
5c3fcae7 117 if (labelfd < 0) {
82b1f317 118 SYSERROR("Unable to open file descriptor to set LSM label.");
81f466d0 119 return -1;
5c3fcae7
SG
120 }
121
81f466d0
CB
122 return labelfd;
123}
124
125static int lsm_set_label_at(int lsm_labelfd, int on_exec, char *lsm_label)
126{
127 int fret = -1;
128 const char* name;
129 char *command = NULL;
130
131 name = lsm_name();
132
133 if (strcmp(name, "nop") == 0)
134 return 0;
135
136 if (strcmp(name, "none") == 0)
137 return 0;
138
139 /* We don't support on-exec with AppArmor */
140 if (strcmp(name, "AppArmor") == 0)
141 on_exec = 0;
142
5c3fcae7
SG
143 if (strcmp(name, "AppArmor") == 0) {
144 int size;
145
146 command = malloc(strlen(lsm_label) + strlen("changeprofile ") + 1);
147 if (!command) {
148 SYSERROR("Failed to write apparmor profile");
5c3fcae7
SG
149 goto out;
150 }
151
152 size = sprintf(command, "changeprofile %s", lsm_label);
153 if (size < 0) {
154 SYSERROR("Failed to write apparmor profile");
5c3fcae7
SG
155 goto out;
156 }
157
81f466d0
CB
158 if (write(lsm_labelfd, command, size + 1) < 0) {
159 SYSERROR("Unable to set LSM label: %s.", command);
5c3fcae7
SG
160 goto out;
161 }
81f466d0
CB
162 INFO("Set LSM label to: %s.", command);
163 } else if (strcmp(name, "SELinux") == 0) {
164 if (write(lsm_labelfd, lsm_label, strlen(lsm_label) + 1) < 0) {
5c3fcae7 165 SYSERROR("Unable to set LSM label");
5c3fcae7
SG
166 goto out;
167 }
81f466d0
CB
168 INFO("Set LSM label to: %s.", lsm_label);
169 } else {
5c3fcae7 170 ERROR("Unable to restore label for unknown LSM: %s", name);
5c3fcae7
SG
171 goto out;
172 }
81f466d0 173 fret = 0;
5c3fcae7
SG
174
175out:
176 free(command);
177
81f466d0
CB
178 if (lsm_labelfd != -1)
179 close(lsm_labelfd);
5c3fcae7 180
81f466d0 181 return fret;
5c3fcae7
SG
182}
183
74a3920a 184static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
e0732705
CS
185{
186 struct lxc_proc_context_info *info = calloc(1, sizeof(*info));
187 FILE *proc_file;
188 char proc_fn[MAXPATHLEN];
460a1cf0 189 char *line = NULL;
e0732705 190 size_t line_bufsz = 0;
460a1cf0 191 int ret, found;
e0732705
CS
192
193 if (!info) {
194 SYSERROR("Could not allocate memory.");
195 return NULL;
196 }
197
198 /* read capabilities */
199 snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", pid);
200
201 proc_file = fopen(proc_fn, "r");
202 if (!proc_file) {
203 SYSERROR("Could not open %s", proc_fn);
204 goto out_error;
205 }
206
207 found = 0;
208 while (getline(&line, &line_bufsz, proc_file) != -1) {
209 ret = sscanf(line, "CapBnd: %llx", &info->capability_mask);
210 if (ret != EOF && ret > 0) {
211 found = 1;
212 break;
213 }
214 }
215
f10fad2f 216 free(line);
e0732705
CS
217 fclose(proc_file);
218
219 if (!found) {
220 SYSERROR("Could not read capability bounding set from %s", proc_fn);
221 errno = ENOENT;
222 goto out_error;
223 }
224
fe4de9a6 225 info->lsm_label = lsm_process_label_get(pid);
e0732705 226
e0732705
CS
227 return info;
228
229out_error:
460a1cf0 230 free(info);
e0732705
CS
231 return NULL;
232}
233
fe4de9a6
DE
234static void lxc_proc_put_context_info(struct lxc_proc_context_info *ctx)
235{
f10fad2f 236 free(ctx->lsm_label);
2c4ea790
SH
237 if (ctx->container)
238 lxc_container_put(ctx->container);
fe4de9a6
DE
239 free(ctx);
240}
241
74a3920a 242static int lxc_attach_to_ns(pid_t pid, int which)
99d50954 243{
26818618 244 int fd[LXC_NS_MAX];
fc763ab7
CS
245 int i, j, saved_errno;
246
99d50954 247
a052913d 248 if (access("/proc/self/ns", X_OK)) {
99d50954
CS
249 ERROR("Does this kernel version support 'attach' ?");
250 return -1;
251 }
252
26818618 253 for (i = 0; i < LXC_NS_MAX; i++) {
fc763ab7
CS
254 /* ignore if we are not supposed to attach to that
255 * namespace
256 */
26818618 257 if (which != -1 && !(which & ns_info[i].clone_flag)) {
fc763ab7
CS
258 fd[i] = -1;
259 continue;
260 }
261
26818618 262 fd[i] = lxc_preserve_ns(pid, ns_info[i].proc_name);
99d50954 263 if (fd[i] < 0) {
fc763ab7
CS
264 saved_errno = errno;
265
266 /* close all already opened file descriptors before
267 * we return an error, so we don't leak them
268 */
269 for (j = 0; j < i; j++)
270 close(fd[j]);
271
272 errno = saved_errno;
26818618 273 SYSERROR("failed to open namespace: '%s'.", ns_info[i].proc_name);
99d50954
CS
274 return -1;
275 }
276 }
277
26818618
CB
278 for (i = 0; i < LXC_NS_MAX; i++) {
279 if (fd[i] < 0)
280 continue;
281
282 if (setns(fd[i], 0) < 0) {
fc763ab7
CS
283 saved_errno = errno;
284
26818618 285 for (j = i; j < LXC_NS_MAX; j++)
fc763ab7
CS
286 close(fd[j]);
287
288 errno = saved_errno;
26818618 289 SYSERROR("Failed to attach to namespace \"%s\".", ns_info[i].proc_name);
99d50954
CS
290 return -1;
291 }
292
26818618
CB
293 DEBUG("Attached to namespace \"%s\".", ns_info[i].proc_name);
294
99d50954
CS
295 close(fd[i]);
296 }
297
298 return 0;
299}
300
74a3920a 301static int lxc_attach_remount_sys_proc(void)
7a0b0b56
CS
302{
303 int ret;
304
305 ret = unshare(CLONE_NEWNS);
306 if (ret < 0) {
307 SYSERROR("failed to unshare mount namespace");
308 return -1;
309 }
310
2c6f3fc9
SH
311 if (detect_shared_rootfs()) {
312 if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
313 SYSERROR("Failed to make / rslave");
314 ERROR("Continuing...");
315 }
316 }
317
7a0b0b56
CS
318 /* assume /proc is always mounted, so remount it */
319 ret = umount2("/proc", MNT_DETACH);
320 if (ret < 0) {
321 SYSERROR("failed to unmount /proc");
322 return -1;
323 }
324
325 ret = mount("none", "/proc", "proc", 0, NULL);
326 if (ret < 0) {
327 SYSERROR("failed to remount /proc");
328 return -1;
329 }
330
331 /* try to umount /sys - if it's not a mount point,
332 * we'll get EINVAL, then we ignore it because it
333 * may not have been mounted in the first place
334 */
335 ret = umount2("/sys", MNT_DETACH);
336 if (ret < 0 && errno != EINVAL) {
337 SYSERROR("failed to unmount /sys");
338 return -1;
339 } else if (ret == 0) {
340 /* remount it */
341 ret = mount("none", "/sys", "sysfs", 0, NULL);
342 if (ret < 0) {
343 SYSERROR("failed to remount /sys");
344 return -1;
345 }
346 }
347
348 return 0;
349}
350
74a3920a 351static int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx)
e0732705
CS
352{
353 int last_cap = lxc_caps_last_cap();
354 int cap;
355
356 for (cap = 0; cap <= last_cap; cap++) {
357 if (ctx->capability_mask & (1LL << cap))
358 continue;
359
360 if (prctl(PR_CAPBSET_DROP, cap, 0, 0, 0)) {
361 SYSERROR("failed to remove capability id %d", cap);
362 return -1;
363 }
364 }
365
366 return 0;
367}
905022f7 368
74a3920a 369static int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char** extra_env, char** extra_keep)
b3a39ba6 370{
799f96fd 371 if (policy == LXC_ATTACH_CLEAR_ENV) {
3d5e9f48 372 char **extra_keep_store = NULL;
3d5e9f48
CS
373 int path_kept = 0;
374
375 if (extra_keep) {
376 size_t count, i;
377
378 for (count = 0; extra_keep[count]; count++);
379
380 extra_keep_store = calloc(count, sizeof(char *));
381 if (!extra_keep_store) {
382 SYSERROR("failed to allocate memory for storing current "
383 "environment variable values that will be kept");
384 return -1;
385 }
386 for (i = 0; i < count; i++) {
387 char *v = getenv(extra_keep[i]);
388 if (v) {
389 extra_keep_store[i] = strdup(v);
390 if (!extra_keep_store[i]) {
391 SYSERROR("failed to allocate memory for storing current "
392 "environment variable values that will be kept");
393 while (i > 0)
394 free(extra_keep_store[--i]);
395 free(extra_keep_store);
396 return -1;
397 }
398 if (strcmp(extra_keep[i], "PATH") == 0)
399 path_kept = 1;
400 }
401 /* calloc sets entire array to zero, so we don't
402 * need an else */
403 }
404 }
405
799f96fd 406 if (clearenv()) {
a9cab7e3 407 char **p;
799f96fd 408 SYSERROR("failed to clear environment");
a9cab7e3
CS
409 if (extra_keep_store) {
410 for (p = extra_keep_store; *p; p++)
411 free(*p);
412 free(extra_keep_store);
413 }
3d5e9f48
CS
414 return -1;
415 }
416
417 if (extra_keep_store) {
418 size_t i;
419 for (i = 0; extra_keep[i]; i++) {
acd4922e
SG
420 if (extra_keep_store[i]) {
421 if (setenv(extra_keep[i], extra_keep_store[i], 1) < 0)
422 SYSERROR("Unable to set environment variable");
423 }
3d5e9f48
CS
424 free(extra_keep_store[i]);
425 }
426 free(extra_keep_store);
427 }
428
429 /* always set a default path; shells and execlp tend
430 * to be fine without it, but there is a disturbing
431 * number of C programs out there that just assume
432 * that getenv("PATH") is never NULL and then die a
433 * painful segfault death. */
cfa70b88 434 if (!path_kept)
511a6936 435 setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 1);
b3a39ba6
DW
436 }
437
438 if (putenv("container=lxc")) {
439 SYSERROR("failed to set environment variable");
440 return -1;
441 }
442
3d5e9f48
CS
443 /* set extra environment variables */
444 if (extra_env) {
445 for (; *extra_env; extra_env++) {
446 /* duplicate the string, just to be on
447 * the safe side, because putenv does not
448 * do it for us */
449 char *p = strdup(*extra_env);
450 /* we just assume the user knows what they
451 * are doing, so we don't do any checks */
452 if (!p) {
453 SYSERROR("failed to allocate memory for additional environment "
454 "variables");
455 return -1;
456 }
457 putenv(p);
458 }
459 }
460
b3a39ba6
DW
461 return 0;
462}
463
74a3920a 464static char *lxc_attach_getpwshell(uid_t uid)
905022f7
CS
465{
466 /* local variables */
467 pid_t pid;
468 int pipes[2];
469 int ret;
470 int fd;
471 char *result = NULL;
472
473 /* we need to fork off a process that runs the
474 * getent program, and we need to capture its
475 * output, so we use a pipe for that purpose
476 */
477 ret = pipe(pipes);
478 if (ret < 0)
479 return NULL;
480
481 pid = fork();
482 if (pid < 0) {
483 close(pipes[0]);
484 close(pipes[1]);
485 return NULL;
486 }
487
488 if (pid) {
489 /* parent process */
490 FILE *pipe_f;
491 char *line = NULL;
492 size_t line_bufsz = 0;
493 int found = 0;
494 int status;
495
496 close(pipes[1]);
497
498 pipe_f = fdopen(pipes[0], "r");
499 while (getline(&line, &line_bufsz, pipe_f) != -1) {
500 char *token;
501 char *saveptr = NULL;
502 long value;
503 char *endptr = NULL;
504 int i;
505
506 /* if we already found something, just continue
507 * to read until the pipe doesn't deliver any more
508 * data, but don't modify the existing data
509 * structure
510 */
511 if (found)
512 continue;
513
514 /* trim line on the right hand side */
bbb8a488 515 for (i = strlen(line); i > 0 && (line[i - 1] == '\n' || line[i - 1] == '\r'); --i)
905022f7
CS
516 line[i - 1] = '\0';
517
518 /* split into tokens: first user name */
519 token = strtok_r(line, ":", &saveptr);
520 if (!token)
521 continue;
522 /* next: dummy password field */
523 token = strtok_r(NULL, ":", &saveptr);
524 if (!token)
525 continue;
526 /* next: user id */
527 token = strtok_r(NULL, ":", &saveptr);
528 value = token ? strtol(token, &endptr, 10) : 0;
529 if (!token || !endptr || *endptr || value == LONG_MIN || value == LONG_MAX)
530 continue;
531 /* dummy sanity check: user id matches */
532 if ((uid_t) value != uid)
533 continue;
534 /* skip fields: gid, gecos, dir, go to next field 'shell' */
535 for (i = 0; i < 4; i++) {
536 token = strtok_r(NULL, ":", &saveptr);
537 if (!token)
538 break;
539 }
540 if (!token)
541 continue;
f10fad2f 542 free(result);
905022f7
CS
543 result = strdup(token);
544
545 /* sanity check that there are no fields after that */
546 token = strtok_r(NULL, ":", &saveptr);
547 if (token)
548 continue;
549
550 found = 1;
551 }
552
553 free(line);
554 fclose(pipe_f);
555 again:
556 if (waitpid(pid, &status, 0) < 0) {
557 if (errno == EINTR)
558 goto again;
559 return NULL;
560 }
561
562 /* some sanity checks: if anything even hinted at going
563 * wrong: we can't be sure we have a valid result, so
564 * we assume we don't
565 */
566
567 if (!WIFEXITED(status))
568 return NULL;
569
570 if (WEXITSTATUS(status) != 0)
571 return NULL;
572
573 if (!found)
574 return NULL;
575
576 return result;
577 } else {
578 /* child process */
579 char uid_buf[32];
580 char *arguments[] = {
581 "getent",
582 "passwd",
583 uid_buf,
584 NULL
585 };
586
587 close(pipes[0]);
588
589 /* we want to capture stdout */
590 dup2(pipes[1], 1);
591 close(pipes[1]);
592
593 /* get rid of stdin/stderr, so we try to associate it
594 * with /dev/null
595 */
596 fd = open("/dev/null", O_RDWR);
597 if (fd < 0) {
598 close(0);
599 close(2);
600 } else {
601 dup2(fd, 0);
602 dup2(fd, 2);
603 close(fd);
604 }
605
606 /* finish argument list */
607 ret = snprintf(uid_buf, sizeof(uid_buf), "%ld", (long) uid);
608 if (ret <= 0)
609 exit(-1);
610
611 /* try to run getent program */
612 (void) execvp("getent", arguments);
613 exit(-1);
614 }
615}
cb3e61fa 616
74a3920a 617static void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid)
cb3e61fa
CS
618{
619 FILE *proc_file;
620 char proc_fn[MAXPATHLEN];
621 char *line = NULL;
622 size_t line_bufsz = 0;
623 int ret;
624 long value = -1;
625 uid_t uid = (uid_t)-1;
626 gid_t gid = (gid_t)-1;
627
628 /* read capabilities */
629 snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", 1);
630
631 proc_file = fopen(proc_fn, "r");
632 if (!proc_file)
633 return;
634
635 while (getline(&line, &line_bufsz, proc_file) != -1) {
636 /* format is: real, effective, saved set user, fs
637 * we only care about real uid
638 */
639 ret = sscanf(line, "Uid: %ld", &value);
640 if (ret != EOF && ret > 0) {
641 uid = (uid_t) value;
642 } else {
643 ret = sscanf(line, "Gid: %ld", &value);
644 if (ret != EOF && ret > 0)
645 gid = (gid_t) value;
646 }
647 if (uid != (uid_t)-1 && gid != (gid_t)-1)
648 break;
649 }
650
651 fclose(proc_file);
652 free(line);
653
654 /* only override arguments if we found something */
655 if (uid != (uid_t)-1)
656 *init_uid = uid;
657 if (gid != (gid_t)-1)
658 *init_gid = gid;
659
660 /* TODO: we should also parse supplementary groups and use
661 * setgroups() to set them */
662}
9c4693b8
CS
663
664struct attach_clone_payload {
665 int ipc_socket;
666 lxc_attach_options_t* options;
667 struct lxc_proc_context_info* init_ctx;
668 lxc_attach_exec_t exec_function;
669 void* exec_payload;
670};
671
672static int attach_child_main(void* data);
673
674/* help the optimizer along if it doesn't know that exit always exits */
5dcc1ca6 675#define rexit(c) do { int __c = (c); _exit(__c); return __c; } while(0)
9c4693b8
CS
676
677/* define default options if no options are supplied by the user */
678static lxc_attach_options_t attach_static_default_options = LXC_ATTACH_OPTIONS_DEFAULT;
679
bd4307f0 680static bool fetch_seccomp(struct lxc_container *c,
ff07d7bb 681 lxc_attach_options_t *options)
2c4ea790 682{
bd7b4e28 683 char *path;
2eef2bda 684
bd4307f0
CB
685 if (!(options->namespaces & CLONE_NEWNS) || !(options->attach_flags & LXC_ATTACH_LSM)) {
686 free(c->lxc_conf->seccomp);
687 c->lxc_conf->seccomp = NULL;
2c4ea790 688 return true;
bd4307f0 689 }
bd7b4e28 690
2e812c16 691 /* Remove current setting. */
bd7b4e28 692 if (!c->set_config_item(c, "lxc.seccomp", "")) {
2c4ea790 693 return false;
bd7b4e28
SG
694 }
695
696 /* Fetch the current profile path over the cmd interface */
697 path = c->get_running_config_item(c, "lxc.seccomp");
698 if (!path) {
bd4307f0 699 INFO("Failed to get running config item for lxc.seccomp.");
bd7b4e28
SG
700 return true;
701 }
702
703 /* Copy the value into the new lxc_conf */
704 if (!c->set_config_item(c, "lxc.seccomp", path)) {
705 free(path);
706 return false;
707 }
708 free(path);
709
710 /* Attempt to parse the resulting config */
2c4ea790 711 if (lxc_read_seccomp_config(c->lxc_conf) < 0) {
442f5c0f 712 ERROR("Error reading seccomp policy");
2c4ea790
SH
713 return false;
714 }
715
2e812c16
CB
716 INFO("Retrieved seccomp policy.");
717 return true;
718}
719
bd4307f0 720static bool no_new_privs(struct lxc_container *c,
2e812c16
CB
721 lxc_attach_options_t *options)
722{
2e812c16
CB
723 char *val;
724
2e812c16
CB
725 /* Remove current setting. */
726 if (!c->set_config_item(c, "lxc.no_new_privs", "")) {
727 return false;
728 }
729
730 /* Retrieve currently active setting. */
731 val = c->get_running_config_item(c, "lxc.no_new_privs");
732 if (!val) {
733 INFO("Failed to get running config item for lxc.no_new_privs.");
734 return false;
735 }
736
737 /* Set currently active setting. */
738 if (!c->set_config_item(c, "lxc.no_new_privs", val)) {
739 free(val);
740 return false;
741 }
742 free(val);
743
2c4ea790
SH
744 return true;
745}
746
9b8e3c96
SH
747static signed long get_personality(const char *name, const char *lxcpath)
748{
0d7cf7e9 749 char *p = lxc_cmd_get_config_item(name, "lxc.arch", lxcpath);
9b8e3c96
SH
750 signed long ret;
751
752 if (!p)
753 return -1;
754 ret = lxc_config_parse_arch(p);
755 free(p);
756 return ret;
757}
758
9c4693b8
CS
759int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* attached_process)
760{
761 int ret, status;
f4364484 762 pid_t init_pid, pid, attached_pid, expected;
9c4693b8
CS
763 struct lxc_proc_context_info *init_ctx;
764 char* cwd;
765 char* new_cwd;
766 int ipc_sockets[2];
9b8e3c96 767 signed long personality;
9c4693b8
CS
768
769 if (!options)
770 options = &attach_static_default_options;
771
772 init_pid = lxc_cmd_get_init_pid(name, lxcpath);
773 if (init_pid < 0) {
774 ERROR("failed to get the init pid");
775 return -1;
776 }
777
778 init_ctx = lxc_proc_get_context_info(init_pid);
779 if (!init_ctx) {
780 ERROR("failed to get context of the init process, pid = %ld", (long)init_pid);
781 return -1;
782 }
783
9b8e3c96
SH
784 personality = get_personality(name, lxcpath);
785 if (init_ctx->personality < 0) {
786 ERROR("Failed to get personality of the container");
787 lxc_proc_put_context_info(init_ctx);
788 return -1;
789 }
790 init_ctx->personality = personality;
791
ff07d7bb
CB
792 init_ctx->container = lxc_container_new(name, lxcpath);
793 if (!init_ctx->container)
794 return -1;
795
bd4307f0 796 if (!fetch_seccomp(init_ctx->container, options))
2c4ea790
SH
797 WARN("Failed to get seccomp policy");
798
bd4307f0 799 if (!no_new_privs(init_ctx->container, options))
2e812c16
CB
800 WARN("Could not determine whether PR_SET_NO_NEW_PRIVS is set.");
801
9c4693b8
CS
802 cwd = getcwd(NULL, 0);
803
804 /* determine which namespaces the container was created with
805 * by asking lxc-start, if necessary
806 */
807 if (options->namespaces == -1) {
808 options->namespaces = lxc_cmd_get_clone_flags(name, lxcpath);
809 /* call failed */
810 if (options->namespaces == -1) {
811 ERROR("failed to automatically determine the "
812 "namespaces which the container unshared");
813 free(cwd);
fe4de9a6 814 lxc_proc_put_context_info(init_ctx);
9c4693b8
CS
815 return -1;
816 }
817 }
818
819 /* create a socket pair for IPC communication; set SOCK_CLOEXEC in order
820 * to make sure we don't irritate other threads that want to fork+exec away
821 *
822 * IMPORTANT: if the initial process is multithreaded and another call
823 * just fork()s away without exec'ing directly after, the socket fd will
824 * exist in the forked process from the other thread and any close() in
825 * our own child process will not really cause the socket to close properly,
826 * potentiall causing the parent to hang.
827 *
828 * For this reason, while IPC is still active, we have to use shutdown()
829 * if the child exits prematurely in order to signal that the socket
830 * is closed and cannot assume that the child exiting will automatically
831 * do that.
832 *
833 * IPC mechanism: (X is receiver)
834 * initial process intermediate attached
835 * X <--- send pid of
836 * attached proc,
837 * then exit
838 * send 0 ------------------------------------> X
839 * [do initialization]
840 * X <------------------------------------ send 1
841 * [add to cgroup, ...]
842 * send 2 ------------------------------------> X
81f466d0
CB
843 * [set LXC_ATTACH_NO_NEW_PRIVS]
844 * X <------------------------------------ send 3
845 * [open LSM label fd]
846 * send 4 ------------------------------------> X
847 * [set LSM label]
9c4693b8
CS
848 * close socket close socket
849 * run program
850 */
851 ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
852 if (ret < 0) {
853 SYSERROR("could not set up required IPC mechanism for attaching");
854 free(cwd);
fe4de9a6 855 lxc_proc_put_context_info(init_ctx);
9c4693b8
CS
856 return -1;
857 }
858
859 /* create intermediate subprocess, three reasons:
860 * 1. runs all pthread_atfork handlers and the
861 * child will no longer be threaded
862 * (we can't properly setns() in a threaded process)
863 * 2. we can't setns() in the child itself, since
864 * we want to make sure we are properly attached to
865 * the pidns
866 * 3. also, the initial thread has to put the attached
867 * process into the cgroup, which we can only do if
868 * we didn't already setns() (otherwise, user
869 * namespaces will hate us)
870 */
871 pid = fork();
872
873 if (pid < 0) {
874 SYSERROR("failed to create first subprocess");
875 free(cwd);
fe4de9a6 876 lxc_proc_put_context_info(init_ctx);
9c4693b8
CS
877 return -1;
878 }
879
880 if (pid) {
81f466d0 881 int procfd = -1;
9c4693b8 882 pid_t to_cleanup_pid = pid;
9c4693b8 883
ec64264d 884 /* initial thread, we close the socket that is for the
9c4693b8
CS
885 * subprocesses
886 */
887 close(ipc_sockets[1]);
888 free(cwd);
889
f4364484
SG
890 /* attach to cgroup, if requested */
891 if (options->attach_flags & LXC_ATTACH_MOVE_TO_CGROUP) {
4fb3cba5 892 if (!cgroup_attach(name, lxcpath, pid))
f4364484 893 goto cleanup_error;
f4364484
SG
894 }
895
81f466d0
CB
896 /* Open /proc before setns() to the containers namespace so we
897 * don't rely on any information from inside the container.
898 */
899 procfd = open("/proc", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
900 if (procfd < 0) {
901 SYSERROR("Unable to open /proc.");
902 goto cleanup_error;
903 }
904
f4364484
SG
905 /* Let the child process know to go ahead */
906 status = 0;
907 ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status));
908 if (ret <= 0) {
909 ERROR("error using IPC to notify attached process for initialization (0)");
910 goto cleanup_error;
911 }
912
9c4693b8
CS
913 /* get pid from intermediate process */
914 ret = lxc_read_nointr_expect(ipc_sockets[0], &attached_pid, sizeof(attached_pid), NULL);
915 if (ret <= 0) {
916 if (ret != 0)
917 ERROR("error using IPC to receive pid of attached process");
918 goto cleanup_error;
919 }
920
2eef2bda 921 /* ignore SIGKILL (CTRL-C) and SIGQUIT (CTRL-\) - issue #313 */
62183f1a
SH
922 if (options->stdin_fd == 0) {
923 signal(SIGINT, SIG_IGN);
924 signal(SIGQUIT, SIG_IGN);
925 }
2eef2bda 926
9c4693b8
CS
927 /* reap intermediate process */
928 ret = wait_for_pid(pid);
929 if (ret < 0)
930 goto cleanup_error;
931
932 /* we will always have to reap the grandchild now */
933 to_cleanup_pid = attached_pid;
934
935 /* tell attached process it may start initializing */
936 status = 0;
937 ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status));
938 if (ret <= 0) {
939 ERROR("error using IPC to notify attached process for initialization (0)");
940 goto cleanup_error;
941 }
942
943 /* wait for the attached process to finish initializing */
944 expected = 1;
945 ret = lxc_read_nointr_expect(ipc_sockets[0], &status, sizeof(status), &expected);
946 if (ret <= 0) {
947 if (ret != 0)
81f466d0
CB
948 ERROR("error using IPC to receive notification "
949 "from attached process (1)");
9c4693b8
CS
950 goto cleanup_error;
951 }
952
9c4693b8
CS
953 /* tell attached process we're done */
954 status = 2;
955 ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status));
956 if (ret <= 0) {
81f466d0
CB
957 ERROR("Error using IPC to notify attached process for "
958 "initialization (2): %s.", strerror(errno));
9c4693b8
CS
959 goto cleanup_error;
960 }
961
81f466d0
CB
962 /* Wait for the (grand)child to tell us that it's ready to set
963 * up its LSM labels.
964 */
965 expected = 3;
966 ret = lxc_read_nointr_expect(ipc_sockets[0], &status, sizeof(status), &expected);
967 if (ret <= 0) {
968 ERROR("Error using IPC for the child to tell us to open LSM fd (3): %s.",
969 strerror(errno));
970 goto cleanup_error;
971 }
972
973 /* Open LSM fd and send it to child. */
974 if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) {
975 int on_exec, labelfd;
976 on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? 1 : 0;
977 /* Open fd for the LSM security module. */
978 labelfd = lsm_openat(procfd, attached_pid, on_exec);
979 if (labelfd < 0)
980 goto cleanup_error;
981
982 /* Send child fd of the LSM security module to write to. */
983 ret = lxc_abstract_unix_send_fd(ipc_sockets[0], labelfd, NULL, 0);
984 if (ret <= 0) {
985 ERROR("Error using IPC to send child LSM fd (4): %s.",
986 strerror(errno));
987 goto cleanup_error;
988 }
989 }
990
9c4693b8
CS
991 /* now shut down communication with child, we're done */
992 shutdown(ipc_sockets[0], SHUT_RDWR);
993 close(ipc_sockets[0]);
fe4de9a6 994 lxc_proc_put_context_info(init_ctx);
9c4693b8
CS
995
996 /* we're done, the child process should now execute whatever
997 * it is that the user requested. The parent can now track it
998 * with waitpid() or similar.
999 */
1000
1001 *attached_process = attached_pid;
1002 return 0;
1003
1004 cleanup_error:
1005 /* first shut down the socket, then wait for the pid,
1006 * otherwise the pid we're waiting for may never exit
1007 */
81f466d0
CB
1008 if (procfd >= 0)
1009 close(procfd);
9c4693b8
CS
1010 shutdown(ipc_sockets[0], SHUT_RDWR);
1011 close(ipc_sockets[0]);
1012 if (to_cleanup_pid)
1013 (void) wait_for_pid(to_cleanup_pid);
fe4de9a6 1014 lxc_proc_put_context_info(init_ctx);
9c4693b8
CS
1015 return -1;
1016 }
1017
1018 /* first subprocess begins here, we close the socket that is for the
1019 * initial thread
1020 */
1021 close(ipc_sockets[0]);
1022
f4364484
SG
1023 /* Wait for the parent to have setup cgroups */
1024 expected = 0;
1025 status = -1;
1026 ret = lxc_read_nointr_expect(ipc_sockets[1], &status, sizeof(status), &expected);
1027 if (ret <= 0) {
1028 ERROR("error communicating with child process");
1029 shutdown(ipc_sockets[1], SHUT_RDWR);
1030 rexit(-1);
1031 }
1032
dac862c0 1033 if ((options->attach_flags & LXC_ATTACH_MOVE_TO_CGROUP) && cgns_supported())
1034 options->namespaces |= CLONE_NEWCGROUP;
fe3c80af 1035
9c4693b8
CS
1036 /* attach now, create another subprocess later, since pid namespaces
1037 * only really affect the children of the current process
1038 */
1039 ret = lxc_attach_to_ns(init_pid, options->namespaces);
1040 if (ret < 0) {
1041 ERROR("failed to enter the namespace");
1042 shutdown(ipc_sockets[1], SHUT_RDWR);
1043 rexit(-1);
1044 }
1045
1046 /* attach succeeded, try to cwd */
1047 if (options->initial_cwd)
1048 new_cwd = options->initial_cwd;
1049 else
1050 new_cwd = cwd;
1051 ret = chdir(new_cwd);
1052 if (ret < 0)
1053 WARN("could not change directory to '%s'", new_cwd);
1054 free(cwd);
1055
1056 /* now create the real child process */
1057 {
1058 struct attach_clone_payload payload = {
1059 .ipc_socket = ipc_sockets[1],
1060 .options = options,
1061 .init_ctx = init_ctx,
1062 .exec_function = exec_function,
5c3fcae7 1063 .exec_payload = exec_payload,
9c4693b8
CS
1064 };
1065 /* We use clone_parent here to make this subprocess a direct child of
1066 * the initial process. Then this intermediate process can exit and
1067 * the parent can directly track the attached process.
1068 */
1069 pid = lxc_clone(attach_child_main, &payload, CLONE_PARENT);
1070 }
1071
1072 /* shouldn't happen, clone() should always return positive pid */
1073 if (pid <= 0) {
1074 SYSERROR("failed to create subprocess");
1075 shutdown(ipc_sockets[1], SHUT_RDWR);
1076 rexit(-1);
1077 }
1078
1079 /* tell grandparent the pid of the pid of the newly created child */
1080 ret = lxc_write_nointr(ipc_sockets[1], &pid, sizeof(pid));
1081 if (ret != sizeof(pid)) {
1082 /* if this really happens here, this is very unfortunate, since the
1083 * parent will not know the pid of the attached process and will
1084 * not be able to wait for it (and we won't either due to CLONE_PARENT)
1085 * so the parent won't be able to reap it and the attached process
1086 * will remain a zombie
1087 */
1088 ERROR("error using IPC to notify main process of pid of the attached process");
1089 shutdown(ipc_sockets[1], SHUT_RDWR);
1090 rexit(-1);
1091 }
1092
1093 /* the rest is in the hands of the initial and the attached process */
1094 rexit(0);
1095}
1096
74a3920a 1097static int attach_child_main(void* data)
9c4693b8
CS
1098{
1099 struct attach_clone_payload* payload = (struct attach_clone_payload*)data;
1100 int ipc_socket = payload->ipc_socket;
1101 lxc_attach_options_t* options = payload->options;
1102 struct lxc_proc_context_info* init_ctx = payload->init_ctx;
1a2e58cf 1103#if HAVE_SYS_PERSONALITY_H
9c4693b8 1104 long new_personality;
1a2e58cf 1105#endif
9c4693b8
CS
1106 int ret;
1107 int status;
1108 int expected;
1109 long flags;
1110 int fd;
81f466d0 1111 int lsm_labelfd;
9c4693b8
CS
1112 uid_t new_uid;
1113 gid_t new_gid;
1114
1115 /* wait for the initial thread to signal us that it's ready
1116 * for us to start initializing
1117 */
1118 expected = 0;
1119 status = -1;
1120 ret = lxc_read_nointr_expect(ipc_socket, &status, sizeof(status), &expected);
1121 if (ret <= 0) {
81f466d0 1122 ERROR("Error using IPC to receive notification from initial process (0): %s.", strerror(errno));
9c4693b8
CS
1123 shutdown(ipc_socket, SHUT_RDWR);
1124 rexit(-1);
1125 }
1126
9c4693b8
CS
1127 /* A description of the purpose of this functionality is
1128 * provided in the lxc-attach(1) manual page. We have to
1129 * remount here and not in the parent process, otherwise
1130 * /proc may not properly reflect the new pid namespace.
1131 */
1132 if (!(options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_REMOUNT_PROC_SYS)) {
1133 ret = lxc_attach_remount_sys_proc();
1134 if (ret < 0) {
1135 shutdown(ipc_socket, SHUT_RDWR);
1136 rexit(-1);
1137 }
1138 }
1139
1140 /* now perform additional attachments*/
1141#if HAVE_SYS_PERSONALITY_H
1142 if (options->personality < 0)
1143 new_personality = init_ctx->personality;
1144 else
1145 new_personality = options->personality;
1146
1147 if (options->attach_flags & LXC_ATTACH_SET_PERSONALITY) {
1148 ret = personality(new_personality);
1149 if (ret < 0) {
1150 SYSERROR("could not ensure correct architecture");
1151 shutdown(ipc_socket, SHUT_RDWR);
1152 rexit(-1);
1153 }
1154 }
1155#endif
1156
1157 if (options->attach_flags & LXC_ATTACH_DROP_CAPABILITIES) {
1158 ret = lxc_attach_drop_privs(init_ctx);
1159 if (ret < 0) {
1160 ERROR("could not drop privileges");
1161 shutdown(ipc_socket, SHUT_RDWR);
1162 rexit(-1);
1163 }
1164 }
1165
1166 /* always set the environment (specify (LXC_ATTACH_KEEP_ENV, NULL, NULL) if you want this to be a no-op) */
1167 ret = lxc_attach_set_environment(options->env_policy, options->extra_env_vars, options->extra_keep_env);
1168 if (ret < 0) {
1169 ERROR("could not set initial environment for attached process");
1170 shutdown(ipc_socket, SHUT_RDWR);
1171 rexit(-1);
1172 }
1173
1174 /* set user / group id */
1175 new_uid = 0;
1176 new_gid = 0;
1177 /* ignore errors, we will fall back to root in that case
1178 * (/proc was not mounted etc.)
1179 */
1180 if (options->namespaces & CLONE_NEWUSER)
1181 lxc_attach_get_init_uidgid(&new_uid, &new_gid);
1182
1183 if (options->uid != (uid_t)-1)
1184 new_uid = options->uid;
1185 if (options->gid != (gid_t)-1)
1186 new_gid = options->gid;
1187
82e28fe0 1188 /* setup the control tty */
d3b63011 1189 if (options->stdin_fd && isatty(options->stdin_fd)) {
82e28fe0
SG
1190 if (setsid() < 0) {
1191 SYSERROR("unable to setsid");
1192 shutdown(ipc_socket, SHUT_RDWR);
1193 rexit(-1);
1194 }
1195
1196 if (ioctl(options->stdin_fd, TIOCSCTTY, (char *)NULL) < 0) {
1197 SYSERROR("unable to TIOCSTTY");
1198 shutdown(ipc_socket, SHUT_RDWR);
1199 rexit(-1);
1200 }
1201 }
1202
9c4693b8 1203 /* try to set the uid/gid combination */
c476bdce
SH
1204 if ((new_gid != 0 || options->namespaces & CLONE_NEWUSER)) {
1205 if (setgid(new_gid) || setgroups(0, NULL)) {
1206 SYSERROR("switching to container gid");
1207 shutdown(ipc_socket, SHUT_RDWR);
1208 rexit(-1);
1209 }
9c4693b8
CS
1210 }
1211 if ((new_uid != 0 || options->namespaces & CLONE_NEWUSER) && setuid(new_uid)) {
1212 SYSERROR("switching to container uid");
1213 shutdown(ipc_socket, SHUT_RDWR);
1214 rexit(-1);
1215 }
1216
1217 /* tell initial process it may now put us into the cgroups */
1218 status = 1;
1219 ret = lxc_write_nointr(ipc_socket, &status, sizeof(status));
1220 if (ret != sizeof(status)) {
81f466d0 1221 ERROR("Error using IPC to notify initial process for initialization (1): %s.", strerror(errno));
9c4693b8
CS
1222 shutdown(ipc_socket, SHUT_RDWR);
1223 rexit(-1);
1224 }
1225
1226 /* wait for the initial thread to signal us that it has done
1227 * everything for us when it comes to cgroups etc.
1228 */
1229 expected = 2;
1230 status = -1;
1231 ret = lxc_read_nointr_expect(ipc_socket, &status, sizeof(status), &expected);
1232 if (ret <= 0) {
81f466d0
CB
1233 ERROR("Error using IPC to receive message from initial process "
1234 "that it is done pre-initializing (2): %s",
1235 strerror(errno));
9c4693b8
CS
1236 shutdown(ipc_socket, SHUT_RDWR);
1237 rexit(-1);
1238 }
1239
2e812c16
CB
1240 if ((init_ctx->container && init_ctx->container->lxc_conf &&
1241 init_ctx->container->lxc_conf->no_new_privs) ||
1242 (options->attach_flags & LXC_ATTACH_NO_NEW_PRIVS)) {
1243 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1244 SYSERROR("PR_SET_NO_NEW_PRIVS could not be set. "
1245 "Process can use execve() gainable "
1246 "privileges.");
81f466d0 1247 shutdown(ipc_socket, SHUT_RDWR);
2e812c16
CB
1248 rexit(-1);
1249 }
1250 INFO("PR_SET_NO_NEW_PRIVS is set. Process cannot use execve() "
1251 "gainable privileges.");
1252 }
1253
81f466d0
CB
1254 /* Tell the (grand)parent to send us LSM label fd. */
1255 status = 3;
1256 ret = lxc_write_nointr(ipc_socket, &status, sizeof(status));
1257 if (ret <= 0) {
1258 ERROR("Error using IPC to tell parent to set up LSM labels (3): %s.", strerror(errno));
1259 shutdown(ipc_socket, SHUT_RDWR);
1260 rexit(-1);
1261 }
1262
5c3fcae7 1263 if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_LSM) && init_ctx->lsm_label) {
72863294 1264 int on_exec;
81f466d0
CB
1265 /* Receive fd for LSM security module. */
1266 ret = lxc_abstract_unix_recv_fd(ipc_socket, &lsm_labelfd, NULL, 0);
1267 if (ret <= 0) {
1268 ERROR("Error using IPC for parent to tell us LSM label fd (4): %s.", strerror(errno));
1269 shutdown(ipc_socket, SHUT_RDWR);
1270 rexit(-1);
1271 }
72863294 1272
81f466d0 1273 /* Change into our new LSM profile. */
72863294 1274 on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? 1 : 0;
81f466d0
CB
1275 if (lsm_set_label_at(lsm_labelfd, on_exec, init_ctx->lsm_label) < 0) {
1276 SYSERROR("Failed to set LSM label.");
1277 shutdown(ipc_socket, SHUT_RDWR);
1278 close(lsm_labelfd);
72863294
DE
1279 rexit(-1);
1280 }
81f466d0 1281 close(lsm_labelfd);
72863294 1282 }
81f466d0 1283
2c4ea790 1284 if (init_ctx->container && init_ctx->container->lxc_conf &&
bd4307f0
CB
1285 init_ctx->container->lxc_conf->seccomp &&
1286 (lxc_seccomp_load(init_ctx->container->lxc_conf) != 0)) {
2c4ea790 1287 ERROR("Loading seccomp policy");
81f466d0 1288 shutdown(ipc_socket, SHUT_RDWR);
2c4ea790
SH
1289 rexit(-1);
1290 }
81f466d0
CB
1291
1292 shutdown(ipc_socket, SHUT_RDWR);
1293 close(ipc_socket);
fe4de9a6 1294 lxc_proc_put_context_info(init_ctx);
9c4693b8
CS
1295
1296 /* The following is done after the communication socket is
1297 * shut down. That way, all errors that might (though
1298 * unlikely) occur up until this point will have their messages
1299 * printed to the original stderr (if logging is so configured)
1300 * and not the fd the user supplied, if any.
1301 */
1302
1303 /* fd handling for stdin, stdout and stderr;
1304 * ignore errors here, user may want to make sure
1305 * the fds are closed, for example */
1306 if (options->stdin_fd >= 0 && options->stdin_fd != 0)
1307 dup2(options->stdin_fd, 0);
1308 if (options->stdout_fd >= 0 && options->stdout_fd != 1)
1309 dup2(options->stdout_fd, 1);
1310 if (options->stderr_fd >= 0 && options->stderr_fd != 2)
1311 dup2(options->stderr_fd, 2);
1312
1313 /* close the old fds */
1314 if (options->stdin_fd > 2)
1315 close(options->stdin_fd);
1316 if (options->stdout_fd > 2)
1317 close(options->stdout_fd);
1318 if (options->stderr_fd > 2)
1319 close(options->stderr_fd);
1320
1321 /* try to remove CLOEXEC flag from stdin/stdout/stderr,
1322 * but also here, ignore errors */
1323 for (fd = 0; fd <= 2; fd++) {
1324 flags = fcntl(fd, F_GETFL);
1325 if (flags < 0)
1326 continue;
26818618
CB
1327 if (flags & FD_CLOEXEC)
1328 if (fcntl(fd, F_SETFL, flags & ~FD_CLOEXEC) < 0)
71b2940d 1329 SYSERROR("Unable to clear CLOEXEC from fd");
9c4693b8
CS
1330 }
1331
1332 /* we're done, so we can now do whatever the user intended us to do */
1333 rexit(payload->exec_function(payload->exec_payload));
1334}
1335
1336int lxc_attach_run_command(void* payload)
1337{
1338 lxc_attach_command_t* cmd = (lxc_attach_command_t*)payload;
1339
1340 execvp(cmd->program, cmd->argv);
1341 SYSERROR("failed to exec '%s'", cmd->program);
1342 return -1;
1343}
1344
1345int lxc_attach_run_shell(void* payload)
1346{
1347 uid_t uid;
1348 struct passwd *passwd;
1349 char *user_shell;
1350
1351 /* ignore payload parameter */
1352 (void)payload;
1353
1354 uid = getuid();
1355 passwd = getpwuid(uid);
1356
1357 /* this probably happens because of incompatible nss
1358 * implementations in host and container (remember, this
1359 * code is still using the host's glibc but our mount
1360 * namespace is in the container)
1361 * we may try to get the information by spawning a
1362 * [getent passwd uid] process and parsing the result
1363 */
1364 if (!passwd)
1365 user_shell = lxc_attach_getpwshell(uid);
1366 else
1367 user_shell = passwd->pw_shell;
1368
1369 if (user_shell)
acf47e1b 1370 execlp(user_shell, user_shell, (char *)NULL);
9c4693b8
CS
1371
1372 /* executed if either no passwd entry or execvp fails,
1373 * we will fall back on /bin/sh as a default shell
1374 */
acf47e1b 1375 execlp("/bin/sh", "/bin/sh", (char *)NULL);
9c4693b8
CS
1376 SYSERROR("failed to exec shell");
1377 return -1;
1378}