]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/lsm/lsm.c
log: remove strerror() from SYSERROR call
[mirror_lxc.git] / src / lxc / lsm / lsm.c
1 /*
2 * lxc: linux Container library
3 *
4 * Authors:
5 * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>
6 * Copyright © 2012 Canonical Ltd.
7 * Dwight Engen <dwight.engen@oracle.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #define _GNU_SOURCE
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <sys/mount.h>
29 #include <sys/param.h>
30
31 #include "conf.h"
32 #include "log.h"
33 #include "lsm.h"
34
35 lxc_log_define(lxc_lsm, lxc);
36
37 static struct lsm_drv *drv = NULL;
38
39 extern struct lsm_drv *lsm_apparmor_drv_init(void);
40 extern struct lsm_drv *lsm_selinux_drv_init(void);
41 extern struct lsm_drv *lsm_nop_drv_init(void);
42
43 __attribute__((constructor))
44 void lsm_init(void)
45 {
46 if (drv) {
47 INFO("LSM security driver %s", drv->name);
48 return;
49 }
50
51 #if HAVE_APPARMOR
52 drv = lsm_apparmor_drv_init();
53 #endif
54 #if HAVE_SELINUX
55 if (!drv)
56 drv = lsm_selinux_drv_init();
57 #endif
58
59 if (!drv)
60 drv = lsm_nop_drv_init();
61 INFO("Initialized LSM security driver %s", drv->name);
62 }
63
64 int lsm_enabled(void)
65 {
66 if (drv)
67 return drv->enabled();
68 return 0;
69 }
70
71 const char *lsm_name(void)
72 {
73 if (drv)
74 return drv->name;
75 return "none";
76 }
77
78 char *lsm_process_label_get(pid_t pid)
79 {
80 if (!drv) {
81 ERROR("LSM driver not inited");
82 return NULL;
83 }
84 return drv->process_label_get(pid);
85 }
86
87 int lsm_process_label_fd_get(pid_t pid, bool on_exec)
88 {
89 int ret = -1;
90 int labelfd = -1;
91 const char *name;
92 char path[LXC_LSMATTRLEN];
93
94 name = lsm_name();
95
96 if (strcmp(name, "nop") == 0)
97 return 0;
98
99 if (strcmp(name, "none") == 0)
100 return 0;
101
102 /* We don't support on-exec with AppArmor */
103 if (strcmp(name, "AppArmor") == 0)
104 on_exec = 0;
105
106 if (on_exec)
107 ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/exec", pid);
108 else
109 ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/current", pid);
110 if (ret < 0 || ret >= LXC_LSMATTRLEN)
111 return -1;
112
113 labelfd = open(path, O_RDWR);
114 if (labelfd < 0) {
115 SYSERROR("Unable to %s LSM label file descriptor", name);
116 return -1;
117 }
118
119 return labelfd;
120 }
121
122 int lsm_process_label_set_at(int label_fd, const char *label, bool on_exec)
123 {
124 int ret = -1;
125 const char *name;
126
127 name = lsm_name();
128
129 if (strcmp(name, "nop") == 0)
130 return 0;
131
132 if (strcmp(name, "none") == 0)
133 return 0;
134
135 /* We don't support on-exec with AppArmor */
136 if (strcmp(name, "AppArmor") == 0)
137 on_exec = false;
138
139 if (strcmp(name, "AppArmor") == 0) {
140 size_t len;
141 char *command;
142
143 if (on_exec) {
144 ERROR("Changing AppArmor profile on exec not supported");
145 return -EINVAL;
146 }
147
148 len = strlen(label) + strlen("changeprofile ") + 1;
149 command = malloc(len);
150 if (!command)
151 return -1;
152
153 ret = snprintf(command, len, "changeprofile %s", label);
154 if (ret < 0 || (size_t)ret >= len) {
155 free(command);
156 return -1;
157 }
158
159 ret = lxc_write_nointr(label_fd, command, len - 1);
160 free(command);
161 } else if (strcmp(name, "SELinux") == 0) {
162 ret = lxc_write_nointr(label_fd, label, strlen(label));
163 } else {
164 ret = -EINVAL;
165 }
166 if (ret < 0) {
167 SYSERROR("Failed to set %s label \"%s\"", name, label);
168 return -1;
169 }
170
171 INFO("Set %s label to \"%s\"", name, label);
172 return 0;
173 }
174
175 int lsm_process_label_set(const char *label, struct lxc_conf *conf,
176 bool use_default, bool on_exec)
177 {
178 if (!drv) {
179 ERROR("LSM driver not inited");
180 return -1;
181 }
182 return drv->process_label_set(label, conf, use_default, on_exec);
183 }