mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
criu: Remove legacy binfmt_misc handling code
Remove the OpenVZ specific code that was not used outside of the OpenVZ infrastructure in preparation for implementing support for upstream Linux kernel binfmt_misc sandboxing. Signed-off-by: Dmitry Sepp <dmitry.sepp@virtuozzo.com>
This commit is contained in:
parent
100b3087fc
commit
0ae3a9498c
11 changed files with 5 additions and 382 deletions
|
|
@ -2098,7 +2098,6 @@ static int cr_dump_finish(int ret)
|
|||
unsuspend_lsm();
|
||||
network_unlock();
|
||||
delete_link_remaps();
|
||||
clean_cr_time_mounts();
|
||||
}
|
||||
|
||||
if (!ret && opts.lazy_pages)
|
||||
|
|
|
|||
|
|
@ -250,9 +250,6 @@ static int crtools_prepare_shared(void)
|
|||
if (!files_collected() && collect_image(&inet_sk_cinfo))
|
||||
return -1;
|
||||
|
||||
if (collect_binfmt_misc())
|
||||
return -1;
|
||||
|
||||
if (tty_prep_fds())
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,25 +32,6 @@ static int attach_option(struct mount_info *pm, char *opt)
|
|||
return pm->options ? 0 : -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
|
||||
struct binfmt_misc_info {
|
||||
BinfmtMiscEntry *bme;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
LIST_HEAD(binfmt_misc_list);
|
||||
|
||||
static int binfmt_misc_parse_or_collect(struct mount_info *pm)
|
||||
{
|
||||
opts.has_binfmt_misc = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int binfmt_misc_virtual(struct mount_info *pm)
|
||||
{
|
||||
return kerndat_fs_virtualized(KERNDAT_FS_STAT_BINFMT_MISC, pm->s_dev);
|
||||
}
|
||||
|
||||
static int parse_binfmt_misc_entry(struct bfd *f, BinfmtMiscEntry *bme)
|
||||
{
|
||||
while (1) {
|
||||
|
|
@ -98,7 +79,7 @@ static int parse_binfmt_misc_entry(struct bfd *f, BinfmtMiscEntry *bme)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dump_binfmt_misc_entry(int dfd, char *name, struct cr_img *img)
|
||||
static int __maybe_unused dump_binfmt_misc_entry(int dfd, char *name, struct cr_img *img)
|
||||
{
|
||||
BinfmtMiscEntry bme = BINFMT_MISC_ENTRY__INIT;
|
||||
struct bfd f;
|
||||
|
|
@ -131,62 +112,6 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int binfmt_misc_dump(struct mount_info *pm)
|
||||
{
|
||||
static bool dumped = false;
|
||||
struct cr_img *img = NULL;
|
||||
struct dirent *de;
|
||||
DIR *fdir = NULL;
|
||||
int fd, ret;
|
||||
|
||||
ret = binfmt_misc_virtual(pm);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
if (dumped) {
|
||||
pr_err("Second binfmt_misc superblock\n");
|
||||
return -1;
|
||||
}
|
||||
dumped = true;
|
||||
|
||||
fd = open_mountpoint(pm);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
fdir = fdopendir(fd);
|
||||
if (fdir == NULL) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = -1;
|
||||
while ((de = readdir(fdir))) {
|
||||
if (dir_dots(de))
|
||||
continue;
|
||||
if (!strcmp(de->d_name, "register"))
|
||||
continue;
|
||||
if (!strcmp(de->d_name, "status"))
|
||||
continue;
|
||||
|
||||
if (!img) {
|
||||
/* Create image only if an entry exists, i.e. here */
|
||||
img = open_image(CR_FD_BINFMT_MISC, O_DUMP);
|
||||
if (!img)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dump_binfmt_misc_entry(fd, de->d_name, img))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (img)
|
||||
close_image(img);
|
||||
closedir(fdir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int write_binfmt_misc_entry(char *mp, char *buf, BinfmtMiscEntry *bme)
|
||||
{
|
||||
int fd, len, ret = -1;
|
||||
|
|
@ -267,7 +192,7 @@ static int make_bfmtm_magic_str(char *buf, BinfmtMiscEntry *bme)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int binfmt_misc_restore_bme(struct mount_info *mi, BinfmtMiscEntry *bme, char *buf)
|
||||
static int __maybe_unused binfmt_misc_restore_bme(struct mount_info *mi, BinfmtMiscEntry *bme, char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -299,83 +224,6 @@ bad_dump:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int binfmt_misc_restore(struct mount_info *mi)
|
||||
{
|
||||
struct cr_img *img;
|
||||
char *buf;
|
||||
int ret = -1;
|
||||
|
||||
buf = xmalloc(BINFMT_MISC_STR);
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
if (!list_empty(&binfmt_misc_list)) {
|
||||
struct binfmt_misc_info *bmi;
|
||||
|
||||
list_for_each_entry(bmi, &binfmt_misc_list, list) {
|
||||
ret = binfmt_misc_restore_bme(mi, bmi->bme, buf);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
goto free_buf;
|
||||
}
|
||||
|
||||
img = open_image(CR_FD_BINFMT_MISC_OLD, O_RSTR, mi->s_dev);
|
||||
if (!img) {
|
||||
pr_err("Can't open binfmt_misc_old image\n");
|
||||
goto free_buf;
|
||||
} else if (empty_image(img)) {
|
||||
close_image(img);
|
||||
ret = 0;
|
||||
goto free_buf;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
while (ret == 0) {
|
||||
BinfmtMiscEntry *bme;
|
||||
|
||||
ret = pb_read_one_eof(img, &bme, PB_BINFMT_MISC);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
ret = binfmt_misc_restore_bme(mi, bme, buf);
|
||||
|
||||
binfmt_misc_entry__free_unpacked(bme, NULL);
|
||||
}
|
||||
|
||||
close_image(img);
|
||||
free_buf:
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int collect_one_binfmt_misc_entry(void *o, ProtobufCMessage *msg, struct cr_img *img)
|
||||
{
|
||||
struct binfmt_misc_info *bmi = o;
|
||||
|
||||
bmi->bme = pb_msg(msg, BinfmtMiscEntry);
|
||||
list_add_tail(&bmi->list, &binfmt_misc_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct collect_image_info binfmt_misc_cinfo = {
|
||||
.fd_type = CR_FD_BINFMT_MISC,
|
||||
.pb_type = PB_BINFMT_MISC,
|
||||
.priv_size = sizeof(struct binfmt_misc_info),
|
||||
.collect = collect_one_binfmt_misc_entry,
|
||||
};
|
||||
|
||||
int collect_binfmt_misc(void)
|
||||
{
|
||||
return collect_image(&binfmt_misc_cinfo);
|
||||
}
|
||||
#else
|
||||
#define binfmt_misc_dump NULL
|
||||
#define binfmt_misc_restore NULL
|
||||
#define binfmt_misc_parse_or_collect NULL
|
||||
#endif
|
||||
|
||||
static int tmpfs_dump(struct mount_info *pm)
|
||||
{
|
||||
int ret = -1, fd = -1, userns_pid = -1;
|
||||
|
|
@ -689,11 +537,7 @@ static struct fstype fstypes[] = {
|
|||
},
|
||||
{
|
||||
.name = "binfmt_misc",
|
||||
.parse = binfmt_misc_parse_or_collect,
|
||||
.collect = binfmt_misc_parse_or_collect,
|
||||
.code = FSTYPE__BINFMT_MISC,
|
||||
.dump = binfmt_misc_dump,
|
||||
.restore = binfmt_misc_restore,
|
||||
},
|
||||
{
|
||||
.name = "tmpfs",
|
||||
|
|
|
|||
|
|
@ -81,8 +81,6 @@ struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = {
|
|||
FD_ENTRY_F(TMPFS_IMG, "tmpfs-%u.tar.gz", O_NOBUF),
|
||||
FD_ENTRY_F(TMPFS_DEV, "tmpfs-dev-%u.tar.gz", O_NOBUF),
|
||||
FD_ENTRY_F(AUTOFS, "autofs-%u", O_NOBUF),
|
||||
FD_ENTRY(BINFMT_MISC_OLD, "binfmt-misc-%u"),
|
||||
FD_ENTRY(BINFMT_MISC, "binfmt-misc"),
|
||||
FD_ENTRY(TTY_FILES, "tty"),
|
||||
FD_ENTRY(TTY_INFO, "tty-info"),
|
||||
FD_ENTRY_F(TTY_DATA, "tty-data", O_NOBUF),
|
||||
|
|
|
|||
|
|
@ -181,9 +181,6 @@ struct cr_options {
|
|||
bool aufs; /* auto-detected, not via cli */
|
||||
bool overlayfs;
|
||||
int ghost_fiemap;
|
||||
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
|
||||
bool has_binfmt_misc; /* auto-detected */
|
||||
#endif
|
||||
size_t ghost_limit;
|
||||
struct list_head irmap_scan_paths;
|
||||
bool lsm_supplied;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,4 @@ extern int aufs_parse(struct mount_info *mi);
|
|||
/* callback for OverlayFS support */
|
||||
extern int overlayfs_parse(struct mount_info *mi);
|
||||
|
||||
/* FIXME -- remove */
|
||||
extern struct list_head binfmt_misc_list;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -145,14 +145,6 @@ static inline bool mnt_is_nodev_external(struct mount_info *mi)
|
|||
}
|
||||
|
||||
extern struct ns_desc mnt_ns_desc;
|
||||
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
|
||||
extern int collect_binfmt_misc(void);
|
||||
#else
|
||||
static inline int collect_binfmt_misc(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern struct mount_info *mnt_entry_alloc(bool rst);
|
||||
extern void mnt_entry_free(struct mount_info *mi);
|
||||
|
|
@ -191,7 +183,6 @@ extern int ext_mount_parse_auto(char *key);
|
|||
extern int mntns_maybe_create_roots(void);
|
||||
extern int read_mnt_ns_img(void);
|
||||
extern void cleanup_mnt_ns(void);
|
||||
extern void clean_cr_time_mounts(void);
|
||||
|
||||
extern char *get_plain_mountpoint(int mnt_id, char *name);
|
||||
|
||||
|
|
@ -221,8 +212,6 @@ extern int mnt_tree_for_each(struct mount_info *start, int (*fn)(struct mount_in
|
|||
extern char *service_mountpoint(const struct mount_info *mi);
|
||||
|
||||
extern int validate_mounts(struct mount_info *info, bool for_dump);
|
||||
extern __maybe_unused struct mount_info *add_cr_time_mount(struct mount_info *root, char *fsname, const char *path,
|
||||
unsigned int s_dev, bool rst);
|
||||
extern char *resolve_source(struct mount_info *mi);
|
||||
extern int fetch_rt_stat(struct mount_info *m, const char *where);
|
||||
extern int do_simple_mount(struct mount_info *mi, const char *src, const char *fstype, unsigned long mountflags);
|
||||
|
|
|
|||
|
|
@ -360,11 +360,6 @@ static dev_t get_host_dev(unsigned int which)
|
|||
.path = "/dev",
|
||||
.magic = TMPFS_MAGIC,
|
||||
},
|
||||
[KERNDAT_FS_STAT_BINFMT_MISC] = {
|
||||
.name = "binfmt_misc",
|
||||
.path = "/proc/sys/fs/binfmt_misc",
|
||||
.magic = BINFMTFS_MAGIC,
|
||||
},
|
||||
};
|
||||
|
||||
if (which >= KERNDAT_FS_STAT_MAX) {
|
||||
|
|
|
|||
|
|
@ -1289,19 +1289,6 @@ int prepare_mnt_ns_v2(void)
|
|||
if (!(root_ns_mask & CLONE_NEWNS))
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
|
||||
if (!opts.has_binfmt_misc && !list_empty(&binfmt_misc_list)) {
|
||||
/*
|
||||
* Add to root yard along with other plain mounts and mntns
|
||||
* directories. This mount would be created and restored by
|
||||
* generic mount creation code, but it would never be moved to
|
||||
* any restored mount namespaces.
|
||||
*/
|
||||
if (!add_cr_time_mount(root_yard_mp, "binfmt_misc", "binfmt_misc", 0, true))
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (validate_mounts(mntinfo, false))
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
185
criu/mount.c
185
criu/mount.c
|
|
@ -1659,123 +1659,6 @@ char *get_plain_mountpoint(int mnt_id, char *name)
|
|||
return xstrdup(tmp);
|
||||
}
|
||||
|
||||
struct mount_info __maybe_unused *add_cr_time_mount(struct mount_info *root, char *fsname, const char *path,
|
||||
unsigned int s_dev, bool rst)
|
||||
{
|
||||
struct mount_info *mi, *t, *parent;
|
||||
bool add_slash = false;
|
||||
int len;
|
||||
|
||||
mi = mnt_entry_alloc(rst);
|
||||
if (!mi)
|
||||
return NULL;
|
||||
|
||||
len = strlen(root->mountpoint);
|
||||
/* It may be "./" or "./path/to/dir" */
|
||||
if (root->mountpoint[len - 1] != '/') {
|
||||
add_slash = true;
|
||||
len++;
|
||||
}
|
||||
|
||||
mi->mountpoint = xmalloc(len + strlen(path) + 1);
|
||||
if (!mi->mountpoint)
|
||||
goto err;
|
||||
if (!rst)
|
||||
mi->ns_mountpoint = mi->mountpoint;
|
||||
if (!add_slash)
|
||||
sprintf(mi->mountpoint, "%s%s", root->mountpoint, path);
|
||||
else
|
||||
sprintf(mi->mountpoint, "%s/%s", root->mountpoint, path);
|
||||
if (rst) {
|
||||
mi->plain_mountpoint = get_plain_mountpoint(-1, "crtime");
|
||||
if (!mi->plain_mountpoint)
|
||||
goto err;
|
||||
}
|
||||
mi->mnt_id = HELPER_MNT_ID;
|
||||
mi->is_dir = true;
|
||||
mi->flags = mi->sb_flags = 0;
|
||||
mi->root = xstrdup("/");
|
||||
mi->fsname = xstrdup(fsname);
|
||||
mi->source = xstrdup(fsname);
|
||||
mi->options = xstrdup("");
|
||||
if (!mi->root || !mi->fsname || !mi->source || !mi->options)
|
||||
goto err;
|
||||
mi->fstype = find_fstype_by_name(fsname);
|
||||
|
||||
mi->s_dev = mi->s_dev_rt = s_dev;
|
||||
|
||||
parent = root;
|
||||
while (1) {
|
||||
list_for_each_entry(t, &parent->children, siblings) {
|
||||
if (strstartswith(service_mountpoint(mi), service_mountpoint(t))) {
|
||||
parent = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (&t->siblings == &parent->children)
|
||||
break;
|
||||
}
|
||||
|
||||
mi->mnt_bind_is_populated = true;
|
||||
mi->is_overmounted = false;
|
||||
mi->nsid = parent->nsid;
|
||||
mi->parent = parent;
|
||||
mi->parent_mnt_id = parent->mnt_id;
|
||||
list_add(&mi->siblings, &parent->children);
|
||||
pr_info("Add cr-time mountpoint %s with parent %s(%u)\n", service_mountpoint(mi), service_mountpoint(parent),
|
||||
parent->mnt_id);
|
||||
return mi;
|
||||
|
||||
err:
|
||||
mnt_entry_free(mi);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* 0 - success
|
||||
* -1 - error
|
||||
* 1 - skip
|
||||
*/
|
||||
static __maybe_unused int mount_cr_time_mount(struct ns_id *ns, unsigned int *s_dev, const char *source,
|
||||
const char *target, const char *type)
|
||||
{
|
||||
int mnt_fd, cwd_fd, exit_code = -1;
|
||||
struct stat st;
|
||||
|
||||
if (switch_mnt_ns(ns->ns_pid, &mnt_fd, &cwd_fd)) {
|
||||
pr_err("Can't switch mnt_ns\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mount(source, target, type, 0, NULL)) {
|
||||
switch (errno) {
|
||||
case EPERM:
|
||||
case EBUSY:
|
||||
case ENODEV:
|
||||
case ENOENT:
|
||||
pr_debug("Skipping %s as was unable to mount it: %s\n", type, strerror(errno));
|
||||
exit_code = 1;
|
||||
break;
|
||||
default:
|
||||
pr_perror("Unable to mount %s %s %s", type, source, target);
|
||||
}
|
||||
goto restore_ns;
|
||||
}
|
||||
|
||||
if (stat(target, &st)) {
|
||||
pr_perror("Can't stat %s", target);
|
||||
goto restore_ns;
|
||||
}
|
||||
|
||||
*s_dev = MKKDEV(major(st.st_dev), minor(st.st_dev));
|
||||
exit_code = 0;
|
||||
restore_ns:
|
||||
if (restore_mnt_ns(mnt_fd, &cwd_fd))
|
||||
exit_code = -1;
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
static int dump_one_fs(struct mount_info *mi)
|
||||
{
|
||||
struct mount_info *pm = mi;
|
||||
|
|
@ -3517,7 +3400,7 @@ void fini_restore_mntns(void)
|
|||
/*
|
||||
* All nested mount namespaces are restore as sub-trees of the root namespace.
|
||||
*/
|
||||
static int populate_roots_yard(struct mount_info *cr_time)
|
||||
static int populate_roots_yard(void)
|
||||
{
|
||||
struct mnt_remap_entry *r;
|
||||
char path[PATH_MAX];
|
||||
|
|
@ -3548,28 +3431,13 @@ static int populate_roots_yard(struct mount_info *cr_time)
|
|||
}
|
||||
}
|
||||
|
||||
if (cr_time && mkdirpat(AT_FDCWD, service_mountpoint(cr_time), 0755)) {
|
||||
pr_perror("Unable to create %s", service_mountpoint(cr_time));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int populate_mnt_ns(void)
|
||||
{
|
||||
struct mount_info *cr_time = NULL;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
|
||||
if (!opts.has_binfmt_misc && !list_empty(&binfmt_misc_list)) {
|
||||
/* Add to mount tree. Generic code will mount it later */
|
||||
cr_time = add_cr_time_mount(root_yard_mp, "binfmt_misc", "binfmt_misc", 0, true);
|
||||
if (!cr_time)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (resolve_shared_mounts(mntinfo))
|
||||
return -1;
|
||||
|
||||
|
|
@ -3579,7 +3447,7 @@ static int populate_mnt_ns(void)
|
|||
if (find_remap_mounts(root_yard_mp))
|
||||
return -1;
|
||||
|
||||
if (populate_roots_yard(cr_time))
|
||||
if (populate_roots_yard())
|
||||
return -1;
|
||||
|
||||
if (mount_clean_path())
|
||||
|
|
@ -3992,29 +3860,6 @@ int collect_mnt_namespaces(bool for_dump)
|
|||
|
||||
search_bindmounts();
|
||||
|
||||
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
|
||||
if (for_dump && !opts.has_binfmt_misc) {
|
||||
unsigned int s_dev = 0;
|
||||
struct ns_id *ns;
|
||||
|
||||
for (ns = ns_ids; ns != NULL; ns = ns->next) {
|
||||
if (ns->type == NS_ROOT && ns->nd == &mnt_ns_desc)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ns) {
|
||||
ret = mount_cr_time_mount(ns, &s_dev, "binfmt_misc", "/" BINFMT_MISC_HOME, "binfmt_misc");
|
||||
if (ret == -1) {
|
||||
goto err;
|
||||
} else if (ret == 0 && !add_cr_time_mount(ns->mnt.mntinfo_tree, "binfmt_misc", BINFMT_MISC_HOME,
|
||||
s_dev, false)) {
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = resolve_external_mounts(mntinfo);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
@ -4057,32 +3902,6 @@ int dump_mnt_namespaces(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void clean_cr_time_mounts(void)
|
||||
{
|
||||
struct mount_info *mi;
|
||||
int ns_old, ret;
|
||||
|
||||
for (mi = mntinfo; mi; mi = mi->next) {
|
||||
int cwd_fd;
|
||||
|
||||
if (mi->mnt_id != HELPER_MNT_ID)
|
||||
continue;
|
||||
ret = switch_mnt_ns(mi->nsid->ns_pid, &ns_old, &cwd_fd);
|
||||
if (ret) {
|
||||
pr_err("Can't switch to pid's %u mnt_ns\n", mi->nsid->ns_pid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (umount(mi->ns_mountpoint) < 0)
|
||||
pr_perror("Can't umount forced mount %s", mi->ns_mountpoint);
|
||||
|
||||
if (restore_mnt_ns(ns_old, &cwd_fd)) {
|
||||
pr_err("cleanup_forced_mounts exiting with wrong mnt_ns\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ns_desc mnt_ns_desc = NS_DESC_ENTRY(CLONE_NEWNS, "mnt");
|
||||
|
||||
static int call_helper_process(int (*call)(void *), void *arg)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{'flavor': 'ns', 'flags': 'excl suid'}
|
||||
{'flavor': 'ns', 'flags': 'noauto excl suid'}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue