Commit fac7befa authored by Pavel Emelyanov's avatar Pavel Emelyanov

files: Sanity check for reg file on restore is not corrupted

When opening a reg file on restore -- check that the file size we
opened matches the on we saw on dump. This is not bullet-proof protection,
but is helpful to protect against FS updates between dump/restore.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 99cd9695
...@@ -610,6 +610,11 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p) ...@@ -610,6 +610,11 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
rfe.fown = (FownEntry *)&p->fown; rfe.fown = (FownEntry *)&p->fown;
rfe.name = &link->name[1]; rfe.name = &link->name[1];
if (S_ISREG(p->stat.st_mode)) {
rfe.has_size = true;
rfe.size = p->stat.st_size;
}
rfd = fdset_fd(glob_fdset, CR_FD_REG_FILES); rfd = fdset_fd(glob_fdset, CR_FD_REG_FILES);
return pb_write_one(rfd, &rfe, PB_REG_FILE); return pb_write_one(rfd, &rfe, PB_REG_FILE);
...@@ -686,6 +691,29 @@ int open_path(struct file_desc *d, ...@@ -686,6 +691,29 @@ int open_path(struct file_desc *d,
return -1; return -1;
} }
if (rfi->rfe->has_size && !rfi->size_checked) {
struct stat st;
if (fstat(tmp, &st) < 0) {
pr_perror("Can't fstat opened file");
return -1;
}
if (st.st_size != rfi->rfe->size) {
pr_err("File %s has bad size %lu (expect %lu)\n",
rfi->path, st.st_size,
(unsigned long)rfi->rfe->size);
return -1;
}
/*
* This is only visible in the current process, so
* change w/o locks. Other tasks sharing the same
* file will get one via unix sockets.
*/
rfi->size_checked = true;
}
if (rfi->remap) { if (rfi->remap) {
unlink(rfi->path); unlink(rfi->path);
BUG_ON(!rfi->remap->users); BUG_ON(!rfi->remap->users);
...@@ -844,6 +872,7 @@ static int collect_one_regfile(void *o, ProtobufCMessage *base) ...@@ -844,6 +872,7 @@ static int collect_one_regfile(void *o, ProtobufCMessage *base)
rfi->rfe = pb_msg(base, RegFileEntry); rfi->rfe = pb_msg(base, RegFileEntry);
rfi->path = rfi->rfe->name; rfi->path = rfi->rfe->name;
rfi->remap = NULL; rfi->remap = NULL;
rfi->size_checked = false;
pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id); pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id);
return file_desc_add(&rfi->d, rfi->rfe->id, &reg_desc_ops); return file_desc_add(&rfi->d, rfi->rfe->id, &reg_desc_ops);
......
...@@ -20,6 +20,7 @@ struct reg_file_info { ...@@ -20,6 +20,7 @@ struct reg_file_info {
struct file_desc d; struct file_desc d;
RegFileEntry *rfe; RegFileEntry *rfe;
struct file_remap *remap; struct file_remap *remap;
bool size_checked;
char *path; char *path;
}; };
......
...@@ -7,4 +7,5 @@ message reg_file_entry { ...@@ -7,4 +7,5 @@ message reg_file_entry {
required fown_entry fown = 5; required fown_entry fown = 5;
required string name = 6; required string name = 6;
optional sint32 mnt_id = 7 [default = -1]; optional sint32 mnt_id = 7 [default = -1];
optional uint64 size = 8;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment