[CRIU] [PATCH] files: Sanity check for reg file on restore is not corrupted

Pavel Emelyanov xemul at parallels.com
Mon Jun 2 03:32:33 PDT 2014


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: Pavel Emelyanov <xemul at parallels.com>

---
 files-reg.c            | 29 +++++++++++++++++++++++++++++
 include/files-reg.h    |  1 +
 protobuf/regfile.proto |  1 +
 3 files changed, 31 insertions(+)

diff --git a/files-reg.c b/files-reg.c
index 1f23f71..f76116e 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -610,6 +610,11 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
 	rfe.fown	= (FownEntry *)&p->fown;
 	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);
 
 	return pb_write_one(rfd, &rfe, PB_REG_FILE);
@@ -686,6 +691,29 @@ int open_path(struct file_desc *d,
 		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) {
 		unlink(rfi->path);
 		BUG_ON(!rfi->remap->users);
@@ -844,6 +872,7 @@ static int collect_one_regfile(void *o, ProtobufCMessage *base)
 	rfi->rfe = pb_msg(base, RegFileEntry);
 	rfi->path = rfi->rfe->name;
 	rfi->remap = NULL;
+	rfi->size_checked = false;
 
 	pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id);
 	return file_desc_add(&rfi->d, rfi->rfe->id, &reg_desc_ops);
diff --git a/include/files-reg.h b/include/files-reg.h
index 859c661..27f4dd1 100644
--- a/include/files-reg.h
+++ b/include/files-reg.h
@@ -20,6 +20,7 @@ struct reg_file_info {
 	struct file_desc	d;
 	RegFileEntry		*rfe;
 	struct file_remap	*remap;
+	bool			size_checked;
 	char			*path;
 };
 
diff --git a/protobuf/regfile.proto b/protobuf/regfile.proto
index e91dc44..46bec72 100644
--- a/protobuf/regfile.proto
+++ b/protobuf/regfile.proto
@@ -7,4 +7,5 @@ message reg_file_entry {
 	required fown_entry	fown	= 5;
 	required string		name	= 6;
 	optional sint32		mnt_id	= 7 [default = -1];
+	optional uint64		size	= 8;
 }
-- 
1.8.4.2


More information about the CRIU mailing list