mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 23:05:39 +00:00
proc: Sanitize mountinfo parsing
Make the proc_mountinfo obtaned after parse form a single linked list. That's much easier to handle and doesn't have an artificial limitation of 64 items... Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
@@ -91,9 +91,10 @@ struct proc_mountinfo {
|
||||
unsigned int s_dev;
|
||||
char root[64];
|
||||
char mountpoint[64];
|
||||
struct proc_mountinfo *next;
|
||||
};
|
||||
|
||||
extern int parse_mountinfo(pid_t pid, struct proc_mountinfo *mi, int nr_elems);
|
||||
extern struct proc_mountinfo *parse_mountinfo(pid_t pid);
|
||||
extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
|
||||
extern int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s);
|
||||
extern int parse_smaps(pid_t pid, struct list_head *vma_area_list, bool use_map_files);
|
||||
|
28
mount.c
28
mount.c
@@ -15,38 +15,22 @@
|
||||
#include "proc_parse.h"
|
||||
|
||||
static struct proc_mountinfo *mntinfo;
|
||||
static int nr_mntinfo;
|
||||
|
||||
int open_mount(unsigned int s_dev)
|
||||
{
|
||||
static int last = 0;
|
||||
int i;
|
||||
struct proc_mountinfo *i;
|
||||
|
||||
again:
|
||||
for (i = last; i < nr_mntinfo; i++) {
|
||||
if (s_dev == mntinfo[i].s_dev) {
|
||||
last = i;
|
||||
return open(mntinfo[i].mountpoint, O_RDONLY);
|
||||
}
|
||||
}
|
||||
|
||||
if (last) {
|
||||
last = 0;
|
||||
goto again;
|
||||
}
|
||||
for (i = mntinfo; i != NULL; i = i->next)
|
||||
if (s_dev == i->s_dev)
|
||||
return open(i->mountpoint, O_RDONLY);
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int collect_mount_info(void)
|
||||
{
|
||||
nr_mntinfo = 64;
|
||||
mntinfo = xmalloc(sizeof(*mntinfo) * nr_mntinfo);
|
||||
if (!mntinfo)
|
||||
return -1;
|
||||
|
||||
nr_mntinfo = parse_mountinfo(getpid(), mntinfo, nr_mntinfo);
|
||||
if (nr_mntinfo < 1) {
|
||||
mntinfo = parse_mountinfo(getpid());
|
||||
if (!mntinfo) {
|
||||
pr_err("Parsing mountinfo %d failed\n", getpid());
|
||||
return -1;
|
||||
}
|
||||
|
45
proc_parse.c
45
proc_parse.c
@@ -470,44 +470,49 @@ err_parse:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_mountinfo(pid_t pid, struct proc_mountinfo *mi, int nr_elems)
|
||||
struct proc_mountinfo *parse_mountinfo(pid_t pid)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
struct proc_mountinfo *list = NULL;
|
||||
FILE *f;
|
||||
char str[256];
|
||||
int i = 0;
|
||||
|
||||
snprintf(str, sizeof(str), "/proc/%d/mountinfo", pid);
|
||||
f = fopen(str, "r");
|
||||
if (!f) {
|
||||
pr_perror("Can't open %d mountinfo", pid);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fgets(str, sizeof(str), f)) {
|
||||
unsigned int kmaj, kmin, parent_mnt_id;
|
||||
struct proc_mountinfo *new;
|
||||
unsigned int kmaj, kmin;
|
||||
int ret;
|
||||
|
||||
if ((i + 1) >= nr_elems) {
|
||||
i = -ENOMEM;
|
||||
goto out_close;
|
||||
}
|
||||
new = xmalloc(sizeof(*new));
|
||||
if (!new)
|
||||
goto err;
|
||||
|
||||
ret = sscanf(str, "%i %i %u:%u %63s %63s",
|
||||
&mi[i].mnt_id, &parent_mnt_id,
|
||||
&kmaj, &kmin, mi[i].root,
|
||||
mi[i].mountpoint);
|
||||
&new->mnt_id, &new->parent_mnt_id,
|
||||
&kmaj, &kmin, new->root, new->mountpoint);
|
||||
if (ret != 6) {
|
||||
pr_err("Bad format in %d mountinfo\n", pid);
|
||||
i = -1;
|
||||
goto out_close;
|
||||
goto err;
|
||||
}
|
||||
|
||||
mi[i].s_dev = MKKDEV(kmaj, kmin);
|
||||
i++;
|
||||
new->s_dev = MKKDEV(kmaj, kmin);
|
||||
new->next = list;
|
||||
list = new;
|
||||
}
|
||||
|
||||
out_close:
|
||||
fclose(f);
|
||||
out:
|
||||
return i;
|
||||
fclose(f);
|
||||
return list;
|
||||
|
||||
err:
|
||||
while (list) {
|
||||
struct proc_mountinfo *next = list->next;
|
||||
xfree(list);
|
||||
list = next;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
Reference in New Issue
Block a user