mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
criu: kerndat: add kerndat_has_binfmt_misc_sandboxing()
Detect if the kernel supports binfmt_misc sandboxing and store the result in kerndat. The result will be used by the code that dumps and restores binfmt_misc entries. Signed-off-by: Dmitry Sepp <dmitry.sepp@virtuozzo.com>
This commit is contained in:
parent
0ae3a9498c
commit
ecab9e3570
3 changed files with 102 additions and 0 deletions
|
|
@ -1810,6 +1810,16 @@ static int check_external_net_ns(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int check_binfmt_misc_sandboxing(void)
|
||||
{
|
||||
if (!kdat.has_binfmt_misc_sandboxing) {
|
||||
pr_info("binfmt_misc sandboxing isn't supported\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct feature_list {
|
||||
char *name;
|
||||
int (*func)(void);
|
||||
|
|
@ -1861,6 +1871,7 @@ static struct feature_list feature_list[] = {
|
|||
{ "overlayfs_maps", check_overlayfs_maps },
|
||||
{ "breakpoints", check_breakpoints },
|
||||
{ "pagemap_scan_guard_pages", check_pagemap_scan_guard_pages },
|
||||
{ "binfmt_misc_sandboxing", check_binfmt_misc_sandboxing },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ struct kerndat_s {
|
|||
bool has_breakpoints;
|
||||
bool has_madv_guard;
|
||||
bool has_pagemap_scan_guard_pages;
|
||||
bool has_binfmt_misc_sandboxing;
|
||||
};
|
||||
|
||||
extern struct kerndat_s kdat;
|
||||
|
|
|
|||
|
|
@ -1848,6 +1848,92 @@ void kerndat_warn_about_madv_guards(void)
|
|||
"Please, consider updating your kernel.\n");
|
||||
}
|
||||
|
||||
/* Keep the fd open so that it can be closed by the caller (required by the parent process) */
|
||||
static int __mount_and_stat_detached_binfmt_misc(struct stat *st, int *mnt_fd)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = mount_detached_fs("binfmt_misc");
|
||||
if (fd < 0) {
|
||||
/* Most likely a permission error, so we can't use binfmt_misc */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fstat(fd, st) < 0) {
|
||||
pr_perror("Failed to stat a binfmt_misc mountpoint");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*mnt_fd = fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct has_binfmt_misc_arg {
|
||||
dev_t st_dev;
|
||||
bool has;
|
||||
};
|
||||
|
||||
static int __has_binfmt_misc_sandboxing(void *arg)
|
||||
{
|
||||
struct has_binfmt_misc_arg *has_arg = (struct has_binfmt_misc_arg *)arg;
|
||||
struct stat st;
|
||||
int ret, mnt_fd;
|
||||
|
||||
if (unshare(CLONE_NEWNS | CLONE_NEWUSER)) {
|
||||
pr_perror("Failed to unshare namespaces");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = __mount_and_stat_detached_binfmt_misc(&st, &mnt_fd);
|
||||
if (ret < 0) {
|
||||
return 1;
|
||||
} else if (ret == 1) {
|
||||
has_arg->has = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (has_arg->st_dev != st.st_dev)
|
||||
has_arg->has = true;
|
||||
else
|
||||
has_arg->has = false;
|
||||
|
||||
close(mnt_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kerndat_has_binfmt_misc_sandboxing(void)
|
||||
{
|
||||
int ret, mnt_fd;
|
||||
struct stat st;
|
||||
struct has_binfmt_misc_arg arg;
|
||||
|
||||
ret = __mount_and_stat_detached_binfmt_misc(&st, &mnt_fd);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
} else if (ret == 1) {
|
||||
arg.has = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
arg.st_dev = st.st_dev;
|
||||
|
||||
ret = call_in_child_process(__has_binfmt_misc_sandboxing, (void *)&arg);
|
||||
close(mnt_fd);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to check binfmt_misc sandboxing support in child process\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
out:
|
||||
pr_info("binfmt_misc sandboxing is %s supported\n", arg.has ? "" : "not");
|
||||
kdat.has_binfmt_misc_sandboxing = arg.has;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some features depend on resource that can be dynamically changed
|
||||
* at the OS runtime. There are cases that we cannot determine the
|
||||
|
|
@ -2121,6 +2207,10 @@ int kerndat_init(void)
|
|||
pr_err("kerndat_has_madv_guard has failed when initializing kerndat.\n");
|
||||
ret = -1;
|
||||
}
|
||||
if (!ret && kerndat_has_binfmt_misc_sandboxing()) {
|
||||
pr_err("kerndat_has_binfmt_misc_sandboxing has failed when initializing kerndat.\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
kerndat_lsm();
|
||||
kerndat_mmap_min_addr();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue