]> git.proxmox.com Git - mirror_lxc.git/blob - src/tests/aa.c
tests: include config.h
[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 #include "config.h"
21
22 /* Test apparmor rules */
23 #include <lxc/lxccontainer.h>
24 #include "lxc/utils.h"
25
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <string.h>
29
30 #define MYNAME "test-aa"
31
32 static void try_to_remove(void)
33 {
34 struct lxc_container *c;
35 c = lxc_container_new(MYNAME, NULL);
36 if (c) {
37 if (c->is_defined(c))
38 c->destroy(c);
39 lxc_container_put(c);
40 }
41 }
42
43 static int test_attach_write_file(void* payload)
44 {
45 char *fnam = payload;
46 FILE *f;
47
48 f = fopen(fnam, "w");
49 if (f) {
50 printf("yes\n");
51 fclose(f);
52 fflush(NULL);
53 return 1;
54 }
55 printf("no\n");
56 fflush(NULL);
57 return 0;
58 }
59
60 /*
61 * try opening a file attached to a container. Return 0 on open fail. Return
62 * 1 if the file open succeeded. Return -1 if attach itself failed - perhaps an
63 * older kernel.
64 */
65 static int do_test_file_open(struct lxc_container *c, char *fnam)
66 {
67 int fret = -1;
68 int ret;
69 pid_t pid;
70 int pipefd[2];
71 char result[1024];
72 lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
73
74 ret = pipe(pipefd);
75 if (ret < 0) {
76 fprintf(stderr, "pipe failed %d\n", ret);
77 return fret;
78 }
79 attach_options.stdout_fd = pipefd[1];
80 attach_options.attach_flags &= ~(LXC_ATTACH_LSM_EXEC|LXC_ATTACH_DROP_CAPABILITIES);
81 attach_options.attach_flags |= LXC_ATTACH_LSM_NOW;
82 ret = c->attach(c, test_attach_write_file, fnam, &attach_options, &pid);
83 if (ret < 0) {
84 fprintf(stderr, "attach failed\n");
85 goto err1;
86 }
87
88 ret = read(pipefd[0], result, sizeof(result)-1);
89 if (ret < 0) {
90 fprintf(stderr, "read failed %d\n", ret);
91 goto err2;
92 }
93
94 fret = 1;
95 if (strncmp(result, "no", 2) == 0)
96 fret = 0;
97
98 err2:
99 (void)wait_for_pid(pid);
100 err1:
101 close(pipefd[0]);
102 close(pipefd[1]);
103 return fret;
104 }
105
106 char *files_to_allow[] = { "/sys/class/net/lo/ifalias",
107 "/proc/sys/kernel/shmmax",
108 NULL };
109
110 char *files_to_deny[] = {
111 "/sys/kernel/uevent_helper",
112 "/proc/sys/fs/file-nr",
113 "/sys/kernel/mm/ksm/pages_to_scan",
114 "/proc/sys/kernel/sysrq",
115 NULL };
116
117 static bool test_aa_policy(struct lxc_container *c)
118 {
119 int i, ret;
120
121 for (i = 0; files_to_deny[i]; i++) {
122 ret = do_test_file_open(c, files_to_deny[i]);
123 if (ret < 0) {
124 fprintf(stderr, "attach failed; skipping test\n");
125 return true;
126 }
127 if (ret > 0) {
128 fprintf(stderr, "failed - opened %s\n",
129 files_to_deny[i]);
130 return false;
131 }
132 fprintf(stderr, "passed with %s\n", files_to_deny[i]);
133 }
134
135 for (i = 0; files_to_allow[i]; i++) {
136 ret = do_test_file_open(c, files_to_allow[i]);
137 if (ret < 0) {
138 fprintf(stderr, "attach failed; skipping test\n");
139 return true;
140 }
141 if (ret == 0) {
142 fprintf(stderr, "failed - could not open %s\n",
143 files_to_allow[i]);
144 return false;
145 }
146 fprintf(stderr, "passed with %s\n", files_to_allow[i]);
147 }
148
149 return true;
150 }
151
152 int main(int argc, char *argv[])
153 {
154 struct lxc_container *c;
155 try_to_remove();
156 c = lxc_container_new(MYNAME, NULL);
157 if (!c) {
158 fprintf(stderr, "%s: %d: failed to load first container\n", __FILE__, __LINE__);
159 exit(EXIT_FAILURE);
160 }
161
162 if (c->is_defined(c)) {
163 fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
164 goto err;
165 }
166 if (!c->set_config_item(c, "lxc.net.0.type", "empty")) {
167 fprintf(stderr, "%s: %d: failed to set network type\n", __FILE__, __LINE__);
168 goto err;
169 }
170 c->save_config(c, NULL);
171 if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
172 fprintf(stderr, "%s: %d: failed to create container\n", __FILE__, __LINE__);
173 goto err;
174 }
175
176 c->clear_config_item(c, "lxc.mount.auto");
177 c->set_config_item(c, "lxc.mount.entry", "proc proc proc");
178 c->set_config_item(c, "lxc.mount.entry", "sysfs sys sysfs");
179 c->save_config(c, NULL);
180
181 c->want_daemonize(c, true);
182 if (!c->startl(c, 0, NULL)) {
183 fprintf(stderr, "Error starting container\n");
184 goto err;
185 }
186
187 if (!test_aa_policy(c)) {
188 c->stop(c);
189 goto err;
190 }
191
192 c->stop(c);
193
194 try_to_remove();
195 exit(EXIT_SUCCESS);
196
197 err:
198 try_to_remove();
199 exit(EXIT_FAILURE);
200 }