]> git.proxmox.com Git - mirror_lxc.git/blob - src/tests/aa.c
69808b6f3b8a5bb3167a436f6302c5c41b93cfcb
[mirror_lxc.git] / src / tests / aa.c
1 /* liblxcapi
2 *
3 * Copyright © 2014 Serge Hallyn <serge.hallyn@ubuntu.com>.
4 * Copyright © 2014 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 /* Test apparmor rules */
21 #include <lxc/lxccontainer.h>
22 #include "lxc/utils.h"
23
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <string.h>
27
28 #define MYNAME "test-aa"
29
30 static void try_to_remove(void)
31 {
32 struct lxc_container *c;
33 c = lxc_container_new(MYNAME, NULL);
34 if (c) {
35 if (c->is_defined(c))
36 c->destroy(c);
37 lxc_container_put(c);
38 }
39 }
40
41 static int test_attach_write_file(void* payload)
42 {
43 char *fnam = payload;
44 FILE *f;
45
46 f = fopen(fnam, "w");
47 if (f) {
48 printf("yes\n");
49 fclose(f);
50 fflush(NULL);
51 return 1;
52 }
53 printf("no\n");
54 fflush(NULL);
55 return 0;
56 }
57
58 /*
59 * try opening a file attached to a container. Return 0 on open fail. Return
60 * 1 if the file open succeeded. Return -1 if attach itself failed - perhaps an
61 * older kernel.
62 */
63 static int do_test_file_open(struct lxc_container *c, char *fnam)
64 {
65 int fret = -1;
66 int ret;
67 pid_t pid;
68 int pipefd[2];
69 char result[1024];
70 lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
71
72 ret = pipe(pipefd);
73 if (ret < 0) {
74 fprintf(stderr, "pipe failed %d\n", ret);
75 return fret;
76 }
77 attach_options.stdout_fd = pipefd[1];
78 attach_options.attach_flags &= ~(LXC_ATTACH_LSM_EXEC|LXC_ATTACH_DROP_CAPABILITIES);
79 attach_options.attach_flags |= LXC_ATTACH_LSM_NOW;
80 ret = c->attach(c, test_attach_write_file, fnam, &attach_options, &pid);
81 if (ret < 0) {
82 fprintf(stderr, "attach failed\n");
83 goto err1;
84 }
85
86 ret = read(pipefd[0], result, sizeof(result)-1);
87 if (ret < 0) {
88 fprintf(stderr, "read failed %d\n", ret);
89 goto err2;
90 }
91
92 fret = 1;
93 if (strncmp(result, "no", 2) == 0)
94 fret = 0;
95
96 err2:
97 (void)wait_for_pid(pid);
98 err1:
99 close(pipefd[0]);
100 close(pipefd[1]);
101 return fret;
102 }
103
104 char *files_to_allow[] = { "/sys/class/net/lo/ifalias",
105 "/proc/sys/kernel/shmmax",
106 NULL };
107
108 char *files_to_deny[] = {
109 "/sys/kernel/uevent_helper",
110 "/proc/sys/fs/file-nr",
111 "/sys/kernel/mm/ksm/pages_to_scan",
112 "/proc/sys/kernel/sysrq",
113 NULL };
114
115 static bool test_aa_policy(struct lxc_container *c)
116 {
117 int i, ret;
118
119 for (i = 0; files_to_deny[i]; i++) {
120 ret = do_test_file_open(c, files_to_deny[i]);
121 if (ret < 0) {
122 fprintf(stderr, "attach failed; skipping test\n");
123 return true;
124 }
125 if (ret > 0) {
126 fprintf(stderr, "failed - opened %s\n",
127 files_to_deny[i]);
128 return false;
129 }
130 fprintf(stderr, "passed with %s\n", files_to_deny[i]);
131 }
132
133 for (i = 0; files_to_allow[i]; i++) {
134 ret = do_test_file_open(c, files_to_allow[i]);
135 if (ret < 0) {
136 fprintf(stderr, "attach failed; skipping test\n");
137 return true;
138 }
139 if (ret == 0) {
140 fprintf(stderr, "failed - could not open %s\n",
141 files_to_allow[i]);
142 return false;
143 }
144 fprintf(stderr, "passed with %s\n", files_to_allow[i]);
145 }
146
147 return true;
148 }
149
150 int main(int argc, char *argv[])
151 {
152 struct lxc_container *c;
153 try_to_remove();
154 c = lxc_container_new(MYNAME, NULL);
155 if (!c) {
156 fprintf(stderr, "%s: %d: failed to load first container\n", __FILE__, __LINE__);
157 exit(EXIT_FAILURE);
158 }
159
160 if (c->is_defined(c)) {
161 fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
162 goto err;
163 }
164 if (!c->set_config_item(c, "lxc.net.0.type", "empty")) {
165 fprintf(stderr, "%s: %d: failed to set network type\n", __FILE__, __LINE__);
166 goto err;
167 }
168 c->save_config(c, NULL);
169 if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
170 fprintf(stderr, "%s: %d: failed to create container\n", __FILE__, __LINE__);
171 goto err;
172 }
173
174 c->clear_config_item(c, "lxc.mount.auto");
175 c->set_config_item(c, "lxc.mount.entry", "proc proc proc");
176 c->set_config_item(c, "lxc.mount.entry", "sysfs sys sysfs");
177 c->save_config(c, NULL);
178
179 c->want_daemonize(c, true);
180 if (!c->startl(c, 0, NULL)) {
181 fprintf(stderr, "Error starting container\n");
182 goto err;
183 }
184
185 if (!test_aa_policy(c)) {
186 c->stop(c);
187 goto err;
188 }
189
190 c->stop(c);
191
192 try_to_remove();
193 exit(EXIT_SUCCESS);
194
195 err:
196 try_to_remove();
197 exit(EXIT_FAILURE);
198 }