1 |
commit: dbbe51a3b5cddeb4105fffecc3c29be701b10360 |
2 |
Author: Kenton Groombridge <me <AT> concord <DOT> sh> |
3 |
AuthorDate: Tue Jan 11 19:15:24 2022 +0000 |
4 |
Commit: Jason Zaman <perfinion <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Jan 30 01:15:06 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/hardened-refpolicy.git/commit/?id=dbbe51a3 |
7 |
|
8 |
container, docker, rootlesskit: add support for rootless docker |
9 |
|
10 |
Rootless docker runs as root in a user namespace. Because of this, |
11 |
rootless docker containers will run as spc_user_t as docker cannot be |
12 |
SELinux-aware in its own container. |
13 |
|
14 |
Signed-off-by: Kenton Groombridge <me <AT> concord.sh> |
15 |
Signed-off-by: Jason Zaman <perfinion <AT> gentoo.org> |
16 |
|
17 |
policy/modules/services/container.fc | 8 ++ |
18 |
policy/modules/services/container.if | 59 ++++++++++++ |
19 |
policy/modules/services/docker.if | 160 +++++++++++++++++++++++++++++++++ |
20 |
policy/modules/services/docker.te | 82 +++++++++++++++++ |
21 |
policy/modules/services/rootlesskit.te | 3 + |
22 |
5 files changed, 312 insertions(+) |
23 |
|
24 |
diff --git a/policy/modules/services/container.fc b/policy/modules/services/container.fc |
25 |
index 524ccedb..ef5ad3b6 100644 |
26 |
--- a/policy/modules/services/container.fc |
27 |
+++ b/policy/modules/services/container.fc |
28 |
@@ -9,6 +9,14 @@ HOME_DIR/\.local/share/containers/storage/overlay2-layers(/.*)? gen_context(sys |
29 |
HOME_DIR/\.local/share/containers/storage/overlay-images(/.*)? gen_context(system_u:object_r:container_ro_file_t,s0) |
30 |
HOME_DIR/\.local/share/containers/storage/overlay2-images(/.*)? gen_context(system_u:object_r:container_ro_file_t,s0) |
31 |
HOME_DIR/\.local/share/containers/storage/volumes/[^/]+/.* gen_context(system_u:object_r:container_file_t,s0) |
32 |
+HOME_DIR/\.local/share/docker(/.*)? gen_context(system_u:object_r:container_data_home_t,s0) |
33 |
+HOME_DIR/\.local/share/docker/.*/config\.env -- gen_context(system_u:object_r:container_ro_file_t,s0) |
34 |
+HOME_DIR/\.local/share/docker/containers/.*/.*\.log -- gen_context(system_u:object_r:container_log_t,s0) |
35 |
+HOME_DIR/\.local/share/docker/containers/.*/hostname -- gen_context(system_u:object_r:container_ro_file_t,s0) |
36 |
+HOME_DIR/\.local/share/docker/containers/.*/hosts -- gen_context(system_u:object_r:container_ro_file_t,s0) |
37 |
+HOME_DIR/\.local/share/docker/init(/.*)? gen_context(system_u:object_r:container_ro_file_t,s0) |
38 |
+HOME_DIR/\.local/share/docker/fuse-overlayfs(/.*)? gen_context(system_u:object_r:container_ro_file_t,s0) |
39 |
+HOME_DIR/\.local/share/docker/volumes(/.*)? gen_context(system_u:object_r:container_file_t,s0) |
40 |
|
41 |
/usr/bin/crun -- gen_context(system_u:object_r:container_engine_exec_t,s0) |
42 |
/usr/bin/runc -- gen_context(system_u:object_r:container_engine_exec_t,s0) |
43 |
|
44 |
diff --git a/policy/modules/services/container.if b/policy/modules/services/container.if |
45 |
index 28699f52..e9217f63 100644 |
46 |
--- a/policy/modules/services/container.if |
47 |
+++ b/policy/modules/services/container.if |
48 |
@@ -619,6 +619,28 @@ interface(`container_stream_connect_system_containers',` |
49 |
allow $1 container_runtime_t:sock_file read_sock_file_perms; |
50 |
') |
51 |
|
52 |
+######################################## |
53 |
+## <summary> |
54 |
+## Connect to a user container domain |
55 |
+## over a unix stream socket. |
56 |
+## </summary> |
57 |
+## <param name="domain"> |
58 |
+## <summary> |
59 |
+## Domain allowed access. |
60 |
+## </summary> |
61 |
+## </param> |
62 |
+# |
63 |
+interface(`container_stream_connect_user_containers',` |
64 |
+ gen_require(` |
65 |
+ attribute container_user_domain; |
66 |
+ type container_runtime_t; |
67 |
+ ') |
68 |
+ |
69 |
+ files_search_runtime($1) |
70 |
+ stream_connect_pattern($1, container_runtime_t, container_runtime_t, container_user_domain) |
71 |
+ allow $1 container_runtime_t:sock_file read_sock_file_perms; |
72 |
+') |
73 |
+ |
74 |
######################################## |
75 |
## <summary> |
76 |
## Connect to a container domain |
77 |
@@ -661,6 +683,24 @@ interface(`container_signal_all_containers',` |
78 |
allow $1 container_domain:process signal_perms; |
79 |
') |
80 |
|
81 |
+######################################## |
82 |
+## <summary> |
83 |
+## Set the attributes of container ptys. |
84 |
+## </summary> |
85 |
+## <param name="domain"> |
86 |
+## <summary> |
87 |
+## Domain allowed access. |
88 |
+## </summary> |
89 |
+## </param> |
90 |
+# |
91 |
+interface(`container_setattr_container_ptys',` |
92 |
+ gen_require(` |
93 |
+ type container_devpts_t; |
94 |
+ ') |
95 |
+ |
96 |
+ allow $1 container_devpts_t:chr_file setattr; |
97 |
+') |
98 |
+ |
99 |
######################################## |
100 |
## <summary> |
101 |
## Read and write container ptys. |
102 |
@@ -1156,6 +1196,25 @@ interface(`container_manage_user_runtime_files',` |
103 |
manage_files_pattern($1, container_user_runtime_t, container_user_runtime_t) |
104 |
') |
105 |
|
106 |
+######################################## |
107 |
+## <summary> |
108 |
+## Allow the specified domain to read and |
109 |
+## write user runtime container named sockets. |
110 |
+## </summary> |
111 |
+## <param name="domain"> |
112 |
+## <summary> |
113 |
+## Domain allowed access. |
114 |
+## </summary> |
115 |
+## </param> |
116 |
+# |
117 |
+interface(`container_rw_user_runtime_sock_files',` |
118 |
+ gen_require(` |
119 |
+ type container_user_runtime_t; |
120 |
+ ') |
121 |
+ |
122 |
+ allow $1 container_user_runtime_t:sock_file rw_sock_file_perms; |
123 |
+') |
124 |
+ |
125 |
######################################## |
126 |
## <summary> |
127 |
## Allow the specified domain to search |
128 |
|
129 |
diff --git a/policy/modules/services/docker.if b/policy/modules/services/docker.if |
130 |
index 28965cdb..6460ed6e 100644 |
131 |
--- a/policy/modules/services/docker.if |
132 |
+++ b/policy/modules/services/docker.if |
133 |
@@ -46,6 +46,166 @@ interface(`docker_run_cli',` |
134 |
docker_domtrans_cli($1) |
135 |
') |
136 |
|
137 |
+######################################## |
138 |
+## <summary> |
139 |
+## Execute docker in the docker user domain. |
140 |
+## </summary> |
141 |
+## <param name="domain"> |
142 |
+## <summary> |
143 |
+## Domain allowed to transition. |
144 |
+## </summary> |
145 |
+## </param> |
146 |
+# |
147 |
+interface(`docker_domtrans_user_daemon',` |
148 |
+ gen_require(` |
149 |
+ type dockerd_user_t, dockerd_exec_t; |
150 |
+ ') |
151 |
+ |
152 |
+ corecmd_search_bin($1) |
153 |
+ domtrans_pattern($1, dockerd_exec_t, dockerd_user_t) |
154 |
+') |
155 |
+ |
156 |
+######################################## |
157 |
+## <summary> |
158 |
+## Execute docker in the docker user |
159 |
+## domain, and allow the specified |
160 |
+## role the docker user domain. |
161 |
+## </summary> |
162 |
+## <param name="domain"> |
163 |
+## <summary> |
164 |
+## Domain allowed to transition. |
165 |
+## </summary> |
166 |
+## </param> |
167 |
+## <param name="role"> |
168 |
+## <summary> |
169 |
+## The role to be allowed the docker domain. |
170 |
+## </summary> |
171 |
+## </param> |
172 |
+# |
173 |
+interface(`docker_run_user_daemon',` |
174 |
+ gen_require(` |
175 |
+ type dockerd_user_t; |
176 |
+ ') |
177 |
+ |
178 |
+ role $2 types dockerd_user_t; |
179 |
+ |
180 |
+ docker_domtrans_user_daemon($1) |
181 |
+') |
182 |
+ |
183 |
+######################################## |
184 |
+## <summary> |
185 |
+## Execute docker CLI in the docker CLI |
186 |
+## user domain. |
187 |
+## </summary> |
188 |
+## <param name="domain"> |
189 |
+## <summary> |
190 |
+## Domain allowed to transition. |
191 |
+## </summary> |
192 |
+## </param> |
193 |
+# |
194 |
+interface(`docker_domtrans_user_cli',` |
195 |
+ gen_require(` |
196 |
+ type dockerc_user_t, dockerc_exec_t; |
197 |
+ ') |
198 |
+ |
199 |
+ corecmd_search_bin($1) |
200 |
+ domtrans_pattern($1, dockerc_exec_t, dockerc_user_t) |
201 |
+') |
202 |
+ |
203 |
+######################################## |
204 |
+## <summary> |
205 |
+## Execute docker CLI in the docker CLI |
206 |
+## user domain, and allow the specified |
207 |
+## role the docker CLI user domain. |
208 |
+## </summary> |
209 |
+## <param name="domain"> |
210 |
+## <summary> |
211 |
+## Domain allowed to transition. |
212 |
+## </summary> |
213 |
+## </param> |
214 |
+## <param name="role"> |
215 |
+## <summary> |
216 |
+## The role to be allowed the docker |
217 |
+## user domain. |
218 |
+## </summary> |
219 |
+## </param> |
220 |
+# |
221 |
+interface(`docker_run_user_cli',` |
222 |
+ gen_require(` |
223 |
+ type dockerc_user_t; |
224 |
+ ') |
225 |
+ |
226 |
+ role $2 types dockerc_user_t; |
227 |
+ |
228 |
+ docker_domtrans_user_cli($1) |
229 |
+') |
230 |
+ |
231 |
+######################################## |
232 |
+## <summary> |
233 |
+## Role access for rootless docker. |
234 |
+## </summary> |
235 |
+## <param name="role_prefix"> |
236 |
+## <summary> |
237 |
+## The prefix of the user role (e.g., user |
238 |
+## is the prefix for user_r). |
239 |
+## </summary> |
240 |
+## </param> |
241 |
+## <param name="user_domain"> |
242 |
+## <summary> |
243 |
+## User domain for the role. |
244 |
+## </summary> |
245 |
+## </param> |
246 |
+## <param name="user_exec_domain"> |
247 |
+## <summary> |
248 |
+## User exec domain for execute and transition access. |
249 |
+## </summary> |
250 |
+## </param> |
251 |
+## <param name="role"> |
252 |
+## <summary> |
253 |
+## Role allowed access. |
254 |
+## </summary> |
255 |
+## </param> |
256 |
+## <rolecap/> |
257 |
+# |
258 |
+template(`docker_user_role',` |
259 |
+ gen_require(` |
260 |
+ type dockerd_user_t; |
261 |
+ type dockerd_exec_t; |
262 |
+ ') |
263 |
+ |
264 |
+ role $4 types dockerd_user_t; |
265 |
+ |
266 |
+ docker_run_user_daemon($3, $4) |
267 |
+ docker_run_user_cli($3, $4) |
268 |
+ |
269 |
+ ifdef(`init_systemd',` |
270 |
+ systemd_user_daemon_domain($1, dockerd_exec_t, dockerd_user_t) |
271 |
+ systemd_user_send_systemd_notify($1, dockerd_user_t) |
272 |
+ ') |
273 |
+ |
274 |
+ optional_policy(` |
275 |
+ dbus_spec_session_bus_client($1, dockerd_user_t) |
276 |
+ ') |
277 |
+') |
278 |
+ |
279 |
+######################################## |
280 |
+## <summary> |
281 |
+## Send signals to the rootless docker daemon. |
282 |
+## </summary> |
283 |
+## <param name="domain"> |
284 |
+## <summary> |
285 |
+## Domain allowed to transition. |
286 |
+## </summary> |
287 |
+## </param> |
288 |
+# |
289 |
+interface(`docker_signal_user_daemon',` |
290 |
+ gen_require(` |
291 |
+ type dockerd_user_t; |
292 |
+ ') |
293 |
+ |
294 |
+ allow $1 dockerd_user_t:process signal; |
295 |
+') |
296 |
+ |
297 |
######################################## |
298 |
## <summary> |
299 |
## All of the rules required to |
300 |
|
301 |
diff --git a/policy/modules/services/docker.te b/policy/modules/services/docker.te |
302 |
index 27278127..0e2e2e68 100644 |
303 |
--- a/policy/modules/services/docker.te |
304 |
+++ b/policy/modules/services/docker.te |
305 |
@@ -20,6 +20,14 @@ type dockerc_exec_t; |
306 |
container_engine_executable_file(dockerc_t) |
307 |
application_domain(dockerc_t, dockerc_exec_t) |
308 |
|
309 |
+container_engine_domain_template(dockerd_user) |
310 |
+container_user_engine(dockerd_user_t) |
311 |
+application_domain(dockerd_user_t, dockerd_exec_t) |
312 |
+mls_trusted_object(dockerd_user_t) |
313 |
+ |
314 |
+type dockerc_user_t; |
315 |
+application_domain(dockerc_user_t, dockerc_exec_t) |
316 |
+ |
317 |
######################################## |
318 |
# |
319 |
# Docker daemon local policy |
320 |
@@ -83,3 +91,77 @@ miscfiles_read_localization(dockerc_t) |
321 |
userdom_use_user_ptys(dockerc_t) |
322 |
|
323 |
container_stream_connect_system_containers(dockerc_t) |
324 |
+ |
325 |
+######################################## |
326 |
+# |
327 |
+# Rootless Docker daemon local policy |
328 |
+# |
329 |
+ |
330 |
+# rootless docker is really just docker running as root, but in a user namespace |
331 |
+ |
332 |
+allow dockerd_user_t self:netlink_netfilter_socket create_socket_perms; |
333 |
+allow dockerd_user_t self:netlink_xfrm_socket create_socket_perms; |
334 |
+ |
335 |
+fs_getattr_fusefs(dockerd_user_t) |
336 |
+fs_mount_fusefs(dockerd_user_t) |
337 |
+fs_unmount_fusefs(dockerd_user_t) |
338 |
+fs_remount_fusefs(dockerd_user_t) |
339 |
+fs_manage_fusefs_dirs(dockerd_user_t) |
340 |
+fs_manage_fusefs_files(dockerd_user_t) |
341 |
+fs_manage_fusefs_symlinks(dockerd_user_t) |
342 |
+fs_exec_fusefs_files(dockerd_user_t) |
343 |
+fs_mounton_fusefs(dockerd_user_t) |
344 |
+ |
345 |
+kernel_dontaudit_request_load_module(dockerd_user_t) |
346 |
+ |
347 |
+storage_rw_fuse(dockerd_user_t) |
348 |
+ |
349 |
+init_write_runtime_socket(dockerd_user_t) |
350 |
+ |
351 |
+logging_send_syslog_msg(dockerd_user_t) |
352 |
+ |
353 |
+mount_exec(dockerd_user_t) |
354 |
+ |
355 |
+container_setattr_container_ptys(dockerd_user_t) |
356 |
+container_use_container_ptys(dockerd_user_t) |
357 |
+ |
358 |
+rootlesskit_exec(dockerd_user_t) |
359 |
+ |
360 |
+ifdef(`init_systemd',` |
361 |
+ systemd_search_user_runtime(dockerd_user_t) |
362 |
+ systemd_write_user_runtime_socket(dockerd_user_t) |
363 |
+ systemd_start_user_runtime_units(dockerd_user_t) |
364 |
+ systemd_stop_user_runtime_units(dockerd_user_t) |
365 |
+ systemd_status_user_runtime_units(dockerd_user_t) |
366 |
+') |
367 |
+ |
368 |
+optional_policy(` |
369 |
+ dbus_getattr_session_runtime_socket(dockerd_user_t) |
370 |
+ dbus_write_session_runtime_socket(dockerd_user_t) |
371 |
+') |
372 |
+ |
373 |
+######################################## |
374 |
+# |
375 |
+# Rootless Docker CLI local policy |
376 |
+# |
377 |
+ |
378 |
+allow dockerc_user_t self:process { getsched signal }; |
379 |
+allow dockerc_user_t self:fifo_file rw_fifo_file_perms; |
380 |
+ |
381 |
+allow dockerc_user_t dockerd_user_t:unix_stream_socket connectto; |
382 |
+ |
383 |
+corecmd_search_bin(dockerc_user_t) |
384 |
+ |
385 |
+domain_use_interactive_fds(dockerc_user_t) |
386 |
+ |
387 |
+auth_use_nsswitch(dockerc_user_t) |
388 |
+ |
389 |
+miscfiles_read_localization(dockerc_user_t) |
390 |
+ |
391 |
+userdom_use_user_ptys(dockerc_user_t) |
392 |
+userdom_search_user_home_dirs(dockerc_user_t) |
393 |
+userdom_search_user_runtime(dockerc_user_t) |
394 |
+ |
395 |
+xdg_search_data_dirs(dockerc_user_t) |
396 |
+ |
397 |
+container_stream_connect_user_containers(dockerc_user_t) |
398 |
|
399 |
diff --git a/policy/modules/services/rootlesskit.te b/policy/modules/services/rootlesskit.te |
400 |
index 31168801..208143c6 100644 |
401 |
--- a/policy/modules/services/rootlesskit.te |
402 |
+++ b/policy/modules/services/rootlesskit.te |
403 |
@@ -37,6 +37,9 @@ auth_use_nsswitch(rootlesskit_t) |
404 |
|
405 |
userdom_exec_user_bin_files(rootlesskit_t) |
406 |
|
407 |
+docker_domtrans_user_daemon(rootlesskit_t) |
408 |
+docker_signal_user_daemon(rootlesskit_t) |
409 |
+ |
410 |
optional_policy(` |
411 |
dbus_list_system_bus_runtime(rootlesskit_t) |
412 |
dbus_system_bus_client(rootlesskit_t) |