]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/lsm/lsm.c
tree-wide: s/strncpy()/strlcpy()/g
[mirror_lxc.git] / src / lxc / lsm / lsm.c
CommitLineData
fe4de9a6
DE
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
fe4de9a6
DE
24#include <errno.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <sys/mount.h>
28#include <sys/param.h>
29
30#include "conf.h"
31#include "log.h"
1fb5e888 32#include "lsm.h"
fe4de9a6
DE
33
34lxc_log_define(lxc_lsm, lxc);
35
36static struct lsm_drv *drv = NULL;
37
38extern struct lsm_drv *lsm_apparmor_drv_init(void);
39extern struct lsm_drv *lsm_selinux_drv_init(void);
40extern struct lsm_drv *lsm_nop_drv_init(void);
41
42__attribute__((constructor))
43void lsm_init(void)
44{
45 if (drv) {
46 INFO("LSM security driver %s", drv->name);
47 return;
48 }
49
50 #if HAVE_APPARMOR
51 drv = lsm_apparmor_drv_init();
52 #endif
53 #if HAVE_SELINUX
54 if (!drv)
55 drv = lsm_selinux_drv_init();
56 #endif
57
58 if (!drv)
59 drv = lsm_nop_drv_init();
60 INFO("Initialized LSM security driver %s", drv->name);
61}
62
41ca8908 63int lsm_enabled(void)
9e4bf8b1
DE
64{
65 if (drv)
66 return drv->enabled();
67 return 0;
68}
69
41ca8908
DE
70const char *lsm_name(void)
71{
72 if (drv)
73 return drv->name;
74 return "none";
75}
76
fe4de9a6
DE
77char *lsm_process_label_get(pid_t pid)
78{
79 if (!drv) {
80 ERROR("LSM driver not inited");
81 return NULL;
82 }
83 return drv->process_label_get(pid);
84}
85
47ce2cb7
CB
86int lsm_process_label_fd_get(pid_t pid, bool on_exec)
87{
88 int ret = -1;
89 int labelfd = -1;
90 const char *name;
91 char path[LXC_LSMATTRLEN];
92
93 name = lsm_name();
94
95 if (strcmp(name, "nop") == 0)
96 return 0;
97
98 if (strcmp(name, "none") == 0)
99 return 0;
100
101 /* We don't support on-exec with AppArmor */
102 if (strcmp(name, "AppArmor") == 0)
103 on_exec = 0;
104
105 if (on_exec)
106 ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/exec", pid);
107 else
108 ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/current", pid);
109 if (ret < 0 || ret >= LXC_LSMATTRLEN)
110 return -1;
111
112 labelfd = open(path, O_RDWR);
113 if (labelfd < 0) {
114 SYSERROR("%s - Unable to %s LSM label file descriptor",
115 name, strerror(errno));
116 return -1;
117 }
118
119 return labelfd;
120}
121
d3ba7c98
CB
122int 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
7aff4f43 175int lsm_process_label_set(const char *label, struct lxc_conf *conf,
e6e89974 176 bool use_default, bool on_exec)
fe4de9a6
DE
177{
178 if (!drv) {
179 ERROR("LSM driver not inited");
180 return -1;
181 }
7aff4f43 182 return drv->process_label_set(label, conf, use_default, on_exec);
fe4de9a6 183}