]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/namespace.c
utils: use SYSTRACE() when logging stdio permission fixup failures
[mirror_lxc.git] / src / lxc / namespace.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #ifndef _GNU_SOURCE
4 #define _GNU_SOURCE 1
5 #endif
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <sched.h>
9 #include <signal.h>
10 #include <sys/param.h>
11 #include <sys/stat.h>
12 #include <sys/syscall.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15
16 #include "config.h"
17 #include "log.h"
18 #include "memory_utils.h"
19 #include "namespace.h"
20 #include "utils.h"
21
22 lxc_log_define(namespace, lxc);
23
24 /* Leave the user namespace at the first position in the array of structs so
25 * that we always attach to it first when iterating over the struct and using
26 * setns() to switch namespaces. This especially affects lxc_attach(): Suppose
27 * you cloned a new user namespace and mount namespace as an unprivileged user
28 * on the host and want to setns() to the mount namespace. This requires you to
29 * attach to the user namespace first otherwise the kernel will fail this check:
30 *
31 * if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
32 * !ns_capable(current_user_ns(), CAP_SYS_CHROOT) ||
33 * !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
34 * return -EPERM;
35 *
36 * in
37 *
38 * linux/fs/namespace.c:mntns_install().
39 */
40 const struct ns_info ns_info[LXC_NS_MAX] = {
41 [LXC_NS_USER] = { "user", "ns/user", CLONE_NEWUSER, "CLONE_NEWUSER", "LXC_USER_NS" },
42 [LXC_NS_MNT] = { "mnt", "ns/mnt", CLONE_NEWNS, "CLONE_NEWNS", "LXC_MNT_NS" },
43 [LXC_NS_PID] = { "pid", "ns/pid", CLONE_NEWPID, "CLONE_NEWPID", "LXC_PID_NS" },
44 [LXC_NS_UTS] = { "uts", "ns/uts", CLONE_NEWUTS, "CLONE_NEWUTS", "LXC_UTS_NS" },
45 [LXC_NS_IPC] = { "ipc", "ns/ipc", CLONE_NEWIPC, "CLONE_NEWIPC", "LXC_IPC_NS" },
46 [LXC_NS_NET] = { "net", "ns/net", CLONE_NEWNET, "CLONE_NEWNET", "LXC_NET_NS" },
47 [LXC_NS_CGROUP] = { "cgroup", "ns/cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP", "LXC_CGROUP_NS" },
48 [LXC_NS_TIME] = { "time", "ns/time", CLONE_NEWTIME, "CLONE_NEWTIME", "LXC_TIME_NS" },
49 };
50
51 int lxc_namespace_2_cloneflag(const char *namespace)
52 {
53 int i;
54
55 for (i = 0; i < LXC_NS_MAX; i++)
56 if (!strcasecmp(ns_info[i].proc_name, namespace))
57 return ns_info[i].clone_flag;
58
59 ERROR("Invalid namespace name \"%s\"", namespace);
60 return -EINVAL;
61 }
62
63 int lxc_namespace_2_ns_idx(const char *namespace)
64 {
65 int i;
66
67 for (i = 0; i < LXC_NS_MAX; i++)
68 if (!strcmp(ns_info[i].proc_name, namespace))
69 return i;
70
71 ERROR("Invalid namespace name \"%s\"", namespace);
72 return -EINVAL;
73 }
74
75 extern int lxc_namespace_2_std_identifiers(char *namespaces)
76 {
77 char **it;
78 char *del;
79
80 /* The identifiers for namespaces used with lxc-attach and lxc-unshare
81 * as given on the manpage do not align with the standard identifiers.
82 * This affects network, mount, and uts namespaces. The standard identifiers
83 * are: "mnt", "uts", and "net" whereas lxc-attach and lxc-unshare uses
84 * "MOUNT", "UTSNAME", and "NETWORK". So let's use some cheap memmove()s
85 * to replace them by their standard identifiers.
86 * Let's illustrate this with an example:
87 * Assume the string:
88 *
89 * "IPC|MOUNT|PID"
90 *
91 * then we memmove()
92 *
93 * dest: del + 1 == OUNT|PID
94 * src: del + 3 == NT|PID
95 */
96 if (!namespaces)
97 return -1;
98
99 while ((del = strstr(namespaces, "MOUNT")))
100 memmove(del + 1, del + 3, strlen(del) - 2);
101
102 for (it = (char *[]){"NETWORK", "UTSNAME", NULL}; it && *it; it++)
103 while ((del = strstr(namespaces, *it)))
104 memmove(del + 3, del + 7, strlen(del) - 6);
105
106 return 0;
107 }
108
109 int lxc_fill_namespace_flags(char *flaglist, int *flags)
110 {
111 char *token;
112 int aflag;
113
114 if (!flaglist) {
115 ERROR("At least one namespace is needed.");
116 return -1;
117 }
118
119 lxc_iterate_parts(token, flaglist, "|") {
120 aflag = lxc_namespace_2_cloneflag(token);
121 if (aflag < 0)
122 return -1;
123
124 *flags |= aflag;
125 }
126
127 return 0;
128 }