mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-29 13:28:27 +00:00
lsm: also dump and restore sockcreate
The file /proc/PID/attr/sockcreate is used by SELinux to label newly created sockets with the label available at sockcreate. If it is NULL, the default label of the process will be used. This reads out that file during checkpoint and restores the value during restore. This value is irrelevant for existing sockets as they might have been created with another context. This is only to make sure that newly created sockets have the correct context. Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
parent
437561d2bb
commit
ae2ab5ddad
@ -2994,6 +2994,8 @@ static void rst_reloc_creds(struct thread_restore_args *thread_args,
|
||||
|
||||
if (args->lsm_profile)
|
||||
args->lsm_profile = rst_mem_remap_ptr(args->mem_lsm_profile_pos, RM_PRIVATE);
|
||||
if (args->lsm_sockcreate)
|
||||
args->lsm_sockcreate = rst_mem_remap_ptr(args->mem_lsm_sockcreate_pos, RM_PRIVATE);
|
||||
if (args->groups)
|
||||
args->groups = rst_mem_remap_ptr(args->mem_groups_pos, RM_PRIVATE);
|
||||
|
||||
@ -3059,6 +3061,40 @@ rst_prep_creds_args(CredsEntry *ce, unsigned long *prev_pos)
|
||||
args->mem_lsm_profile_pos = 0;
|
||||
}
|
||||
|
||||
if (ce->lsm_sockcreate) {
|
||||
char *rendered = NULL;
|
||||
char *profile;
|
||||
|
||||
profile = ce->lsm_sockcreate;
|
||||
|
||||
if (validate_lsm(profile) < 0)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (profile && render_lsm_profile(profile, &rendered)) {
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
if (rendered) {
|
||||
size_t lsm_sockcreate_len;
|
||||
char *lsm_sockcreate;
|
||||
|
||||
args->mem_lsm_sockcreate_pos = rst_mem_align_cpos(RM_PRIVATE);
|
||||
lsm_sockcreate_len = strlen(rendered);
|
||||
lsm_sockcreate = rst_mem_alloc(lsm_sockcreate_len + 1, RM_PRIVATE);
|
||||
if (!lsm_sockcreate) {
|
||||
xfree(rendered);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
args = rst_mem_remap_ptr(this_pos, RM_PRIVATE);
|
||||
args->lsm_sockcreate = lsm_sockcreate;
|
||||
strncpy(args->lsm_sockcreate, rendered, lsm_sockcreate_len);
|
||||
xfree(rendered);
|
||||
}
|
||||
} else {
|
||||
args->lsm_sockcreate = NULL;
|
||||
args->mem_lsm_sockcreate_pos = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zap fields which we can't use.
|
||||
*/
|
||||
|
@ -69,8 +69,10 @@ struct thread_creds_args {
|
||||
unsigned int secbits;
|
||||
char *lsm_profile;
|
||||
unsigned int *groups;
|
||||
char *lsm_sockcreate;
|
||||
|
||||
unsigned long mem_lsm_profile_pos;
|
||||
unsigned long mem_lsm_sockcreate_pos;
|
||||
unsigned long mem_groups_pos;
|
||||
|
||||
unsigned long mem_pos_next;
|
||||
|
32
criu/lsm.c
32
criu/lsm.c
@ -98,6 +98,32 @@ err:
|
||||
freecon(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* selinux_get_sockcreate_label reads /proc/PID/attr/sockcreate
|
||||
* to see if the PID has a special label specified for sockets.
|
||||
* Most of the time this will be empty and the process will use
|
||||
* the process context also for sockets.
|
||||
*/
|
||||
static int selinux_get_sockcreate_label(pid_t pid, char **output)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen_proc(pid, "attr/sockcreate");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
fscanf(f, "%ms", output);
|
||||
/*
|
||||
* No need to check the result of fscanf(). If there is something
|
||||
* in /proc/PID/attr/sockcreate it will be copied to *output. If
|
||||
* there is nothing it will stay NULL. So whatever fscanf() does
|
||||
* it should be correct.
|
||||
*/
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void kerndat_lsm(void)
|
||||
@ -132,6 +158,7 @@ int collect_lsm_profile(pid_t pid, CredsEntry *ce)
|
||||
int ret;
|
||||
|
||||
ce->lsm_profile = NULL;
|
||||
ce->lsm_sockcreate = NULL;
|
||||
|
||||
switch (kdat.lsm) {
|
||||
case LSMTYPE__NO_LSM:
|
||||
@ -143,6 +170,9 @@ int collect_lsm_profile(pid_t pid, CredsEntry *ce)
|
||||
#ifdef CONFIG_HAS_SELINUX
|
||||
case LSMTYPE__SELINUX:
|
||||
ret = selinux_get_label(pid, &ce->lsm_profile);
|
||||
if (ret)
|
||||
break;
|
||||
ret = selinux_get_sockcreate_label(pid, &ce->lsm_sockcreate);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -153,6 +183,8 @@ int collect_lsm_profile(pid_t pid, CredsEntry *ce)
|
||||
|
||||
if (ce->lsm_profile)
|
||||
pr_info("%d has lsm profile %s\n", pid, ce->lsm_profile);
|
||||
if (ce->lsm_sockcreate)
|
||||
pr_info("%d has lsm sockcreate label %s\n", pid, ce->lsm_sockcreate);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
|
||||
sys_exit_group(1);
|
||||
}
|
||||
|
||||
static int lsm_set_label(char *label, int procfd)
|
||||
static int lsm_set_label(char *label, char *type, int procfd)
|
||||
{
|
||||
int ret = -1, len, lsmfd;
|
||||
char path[STD_LOG_SIMPLE_CHUNK];
|
||||
@ -157,9 +157,9 @@ static int lsm_set_label(char *label, int procfd)
|
||||
if (!label)
|
||||
return 0;
|
||||
|
||||
pr_info("restoring lsm profile %s\n", label);
|
||||
pr_info("restoring lsm profile (%s) %s\n", type, label);
|
||||
|
||||
std_sprintf(path, "self/task/%ld/attr/current", sys_gettid());
|
||||
std_sprintf(path, "self/task/%ld/attr/%s", sys_gettid(), type);
|
||||
|
||||
lsmfd = sys_openat(procfd, path, O_WRONLY, 0);
|
||||
if (lsmfd < 0) {
|
||||
@ -305,9 +305,14 @@ static int restore_creds(struct thread_creds_args *args, int procfd,
|
||||
* SELinux and instead the process context is set before the
|
||||
* threads are created.
|
||||
*/
|
||||
if (lsm_set_label(args->lsm_profile, procfd) < 0)
|
||||
if (lsm_set_label(args->lsm_profile, "current", procfd) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Also set the sockcreate label for all threads */
|
||||
if (lsm_set_label(args->lsm_sockcreate, "sockcreate", procfd) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1571,7 +1576,7 @@ long __export_restore_task(struct task_restore_args *args)
|
||||
if (args->lsm_type == LSMTYPE__SELINUX) {
|
||||
/* Only for SELinux */
|
||||
if (lsm_set_label(args->t->creds_args->lsm_profile,
|
||||
args->proc_fd) < 0)
|
||||
"current", args->proc_fd) < 0)
|
||||
goto core_restore_end;
|
||||
}
|
||||
|
||||
|
@ -20,4 +20,5 @@ message creds_entry {
|
||||
repeated uint32 groups = 14;
|
||||
|
||||
optional string lsm_profile = 15;
|
||||
optional string lsm_sockcreate = 16;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user