]>
Commit | Line | Data |
---|---|---|
8f2c3a70 SH |
1 | /* |
2 | * lxc: linux Container library | |
3 | * | |
4 | * (C) Copyright Canonical, Inc. 2012 | |
5 | * | |
6 | * Authors: | |
7 | * Serge Hallyn <serge.hallyn@canonical.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 | |
250b1eec | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
8f2c3a70 SH |
22 | */ |
23 | ||
24 | #define _GNU_SOURCE | |
25 | #include <stdio.h> | |
26 | #include <stdlib.h> | |
27 | #include <seccomp.h> | |
28 | #include <errno.h> | |
29 | #include <seccomp.h> | |
769872f9 | 30 | #include "config.h" |
8f2c3a70 SH |
31 | #include "lxcseccomp.h" |
32 | ||
33 | #include "log.h" | |
34 | ||
35 | lxc_log_define(lxc_seccomp, lxc); | |
36 | ||
37 | /* | |
38 | * The first line of the config file has a policy language version | |
39 | * the second line has some directives | |
40 | * then comes policy subject to the directives | |
41 | * right now version must be '1' | |
42 | * the directives must include 'whitelist' (only type of policy currently | |
43 | * supported) and can include 'debug' (though debug is not yet supported). | |
44 | */ | |
45 | static int parse_config(FILE *f, struct lxc_conf *conf) | |
46 | { | |
47 | char line[1024]; | |
48 | int ret, version; | |
49 | ||
50 | ret = fscanf(f, "%d\n", &version); | |
51 | if (ret != 1 || version != 1) { | |
52 | ERROR("invalid version"); | |
53 | return -1; | |
54 | } | |
55 | if (!fgets(line, 1024, f)) { | |
56 | ERROR("invalid config file"); | |
57 | return -1; | |
58 | } | |
59 | if (!strstr(line, "whitelist")) { | |
60 | ERROR("only whitelist policy is supported"); | |
61 | return -1; | |
62 | } | |
63 | if (strstr(line, "debug")) { | |
64 | ERROR("debug not yet implemented"); | |
65 | return -1; | |
66 | } | |
67 | /* now read in the whitelist entries one per line */ | |
68 | while (fgets(line, 1024, f)) { | |
69 | int nr; | |
70 | ret = sscanf(line, "%d", &nr); | |
71 | if (ret != 1) | |
72 | return -1; | |
769872f9 SH |
73 | ret = seccomp_rule_add( |
74 | #if HAVE_SCMP_FILTER_CTX | |
75 | conf->seccomp_ctx, | |
76 | #endif | |
77 | SCMP_ACT_ALLOW, nr, 0); | |
8f2c3a70 SH |
78 | if (ret < 0) { |
79 | ERROR("failed loading allow rule for %d\n", nr); | |
80 | return ret; | |
81 | } | |
82 | } | |
83 | return 0; | |
84 | } | |
85 | ||
86 | int lxc_read_seccomp_config(struct lxc_conf *conf) | |
87 | { | |
88 | FILE *f; | |
89 | int ret; | |
90 | ||
769872f9 SH |
91 | if (!conf->seccomp) |
92 | return 0; | |
93 | ||
94 | #if HAVE_SCMP_FILTER_CTX | |
95 | /* XXX for debug, pass in SCMP_ACT_TRAP */ | |
96 | conf->seccomp_ctx = seccomp_init(SCMP_ACT_ERRNO(31)); | |
97 | ret = !conf->seccomp_ctx; | |
98 | #else | |
99 | ret = seccomp_init(SCMP_ACT_ERRNO(31)) < 0; | |
100 | #endif | |
101 | if (ret) { | |
8f2c3a70 SH |
102 | ERROR("failed initializing seccomp"); |
103 | return -1; | |
104 | } | |
8f2c3a70 SH |
105 | |
106 | /* turn of no-new-privs. We don't want it in lxc, and it breaks | |
107 | * with apparmor */ | |
769872f9 SH |
108 | if (seccomp_attr_set( |
109 | #if HAVE_SCMP_FILTER_CTX | |
110 | conf->seccomp_ctx, | |
111 | #endif | |
112 | SCMP_FLTATR_CTL_NNP, 0)) { | |
8f2c3a70 SH |
113 | ERROR("failed to turn off n-new-privs\n"); |
114 | return -1; | |
115 | } | |
116 | ||
117 | f = fopen(conf->seccomp, "r"); | |
118 | if (!f) { | |
119 | SYSERROR("failed to open seccomp policy file %s\n", conf->seccomp); | |
120 | return -1; | |
121 | } | |
122 | ret = parse_config(f, conf); | |
123 | fclose(f); | |
124 | return ret; | |
125 | } | |
126 | ||
127 | int lxc_seccomp_load(struct lxc_conf *conf) | |
128 | { | |
129 | int ret; | |
130 | if (!conf->seccomp) | |
131 | return 0; | |
769872f9 SH |
132 | ret = seccomp_load( |
133 | #if HAVE_SCMP_FILTER_CTX | |
134 | conf->seccomp_ctx | |
135 | #endif | |
136 | ); | |
8f2c3a70 SH |
137 | if (ret < 0) { |
138 | ERROR("Error loading the seccomp policy"); | |
139 | return -1; | |
140 | } | |
141 | return 0; | |
142 | } | |
769872f9 SH |
143 | |
144 | void lxc_seccomp_free(struct lxc_conf *conf) { | |
145 | if (conf->seccomp) { | |
146 | free(conf->seccomp); | |
147 | conf->seccomp = NULL; | |
148 | } | |
149 | #if HAVE_SCMP_FILTER_CTX | |
150 | if (conf->seccomp_ctx) { | |
151 | seccomp_release(conf->seccomp_ctx); | |
152 | conf->seccomp_ctx = NULL; | |
153 | } | |
154 | #endif | |
155 | } |