mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 22:35:33 +00:00
lsm: dump and restore any SELinux process label
There was support for SELinux process labels in CRIU but because it was never tested or verified CRIU only supported the 'unconfined_t' process label. This was basically no SELinux support. For successful container checkpoint and restore on a SELinux enabled host it is necessary that the restored container has the same process context as before checkpointing. This commit only removes the check if the label is 'unconfined_t' and now stores any process label to be restored. For 'normal' processes started from the command-line which are usually running in the 'unconfined_t' this just works. For the container use case this needs additional policies. The latest container-selinux package on Fedora has the necessary policy to allow CRIU (running as 'container_runtime_t' when used from Podman) to transition the restored process to 'container_t'. Restoring a process running under systemd's control (which means 'unconfined_service_t' without additional policies) will fail because CRIU will be not allowed to change the context of the restored process. For each additional CRIU use case on SELinux enabled systems, besides container processes and command-line/shell processes, additional SELinux policies are required to allow CRIU to do a 'dyntransition' (change the Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
committed by
Andrei Vagin
parent
fd1653b851
commit
d9c51a7034
28
criu/lsm.c
28
criu/lsm.c
@@ -62,45 +62,41 @@ static int apparmor_get_label(pid_t pid, char **profile_name)
|
||||
static int selinux_get_label(pid_t pid, char **output)
|
||||
{
|
||||
security_context_t ctx;
|
||||
char *pos, *last;
|
||||
char *pos;
|
||||
int i;
|
||||
int ret = -1;
|
||||
|
||||
if (getpidcon_raw(pid, &ctx) < 0) {
|
||||
pr_perror("getting selinux profile failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*output = NULL;
|
||||
*output = xstrdup((char *)ctx);
|
||||
if (!*output)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Since SELinux attributes can be finer grained than at the task
|
||||
* level, and we currently don't try to dump any of these other bits,
|
||||
* let's only allow unconfined profiles, which look something like:
|
||||
* Make sure it is a valid SELinux label. It should look like this:
|
||||
*
|
||||
* unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
|
||||
*/
|
||||
pos = (char*)ctx;
|
||||
for (i = 0; i < 3; i++) {
|
||||
last = pos;
|
||||
pos = strstr(pos, ":");
|
||||
if (!pos) {
|
||||
pr_err("Invalid selinux context %s\n", (char *)ctx);
|
||||
freecon(ctx);
|
||||
return -1;
|
||||
xfree(*output);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*pos = 0;
|
||||
if (!strstartswith(last, "unconfined_")) {
|
||||
pr_err("Non unconfined selinux contexts not supported %s\n", last);
|
||||
freecon(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
freecon(ctx);
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
err:
|
||||
freecon(ctx);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user