[CRIU] [PATCH 1/2] security: set fs gid to 0 and check img ids and mode when reading

Ruslan Kuprieiev kupruser at gmail.com
Sun Sep 14 22:50:41 PDT 2014


Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
---
 image.c           |  7 +++++++
 include/crtools.h |  1 +
 security.c        | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/image.c b/image.c
index 566073b..904742a 100644
--- a/image.c
+++ b/image.c
@@ -218,6 +218,13 @@ int open_image_at(int dfd, int type, unsigned long flags, ...)
 		goto err;
 	}
 
+	if (flags == O_RDONLY) {
+		if (!check_file_ids(ret)) {
+			pr_err("User has no rights to open image %s\n", path);
+			goto err;
+		}
+	}
+
 	if (fdset_template[type].magic == RAW_IMAGE_MAGIC)
 		goto skip_magic;
 
diff --git a/include/crtools.h b/include/crtools.h
index 75047fc..0f73f27 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -29,5 +29,6 @@ struct proc_status_creds;
 extern bool may_dump(struct proc_status_creds *);
 struct _CredsEntry;
 extern bool may_restore(struct _CredsEntry *);
+extern bool check_file_ids(int fd);
 
 #endif /* __CR_CRTOOLS_H__ */
diff --git a/security.c b/security.c
index a801005..7e225e9 100644
--- a/security.c
+++ b/security.c
@@ -4,6 +4,8 @@
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <sys/fsuid.h>
 
 #include "crtools.h"
 #include "proc_parse.h"
@@ -59,6 +61,15 @@ int restrict_uid(unsigned int uid, unsigned int gid)
 
 	memcpy(cr_groups, buf, cr_ngroups*sizeof(*cr_groups));
 
+	/*
+	 * Make sure criu files(images, logs etc) have not not only root
+	 * owner, but also root group.
+	 */
+	if (setfsgid(0) != cr_gid) {
+		pr_perror("Can't change fs gid\n");
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -164,3 +175,45 @@ bool may_restore(CredsEntry *creds)
 		check_groups(creds->groups, creds->n_groups) &&
 		check_caps(creds->cap_inh, creds->cap_eff, creds->cap_prm);
 }
+
+static char *mode_str(char *buf, mode_t mode)
+{
+	buf[0] = (mode & S_IRUSR) ? 'r' : '-';
+	buf[1] = (mode & S_IWUSR) ? 'w' : '-';
+	buf[2] = (mode & S_IXUSR) ? 'x' : '-';
+	buf[3] = (mode & S_IRGRP) ? 'r' : '-';
+	buf[4] = (mode & S_IWGRP) ? 'w' : '-';
+	buf[5] = (mode & S_IXGRP) ? 'x' : '-';
+	buf[6] = (mode & S_IROTH) ? 'r' : '-';
+	buf[7] = (mode & S_IWOTH) ? 'w' : '-';
+	buf[8] = (mode & S_IXOTH) ? 'x' : '-';
+	buf[9] = '\0';
+
+	return buf;
+}
+
+bool check_file_ids(int fd)
+{
+	struct stat st;
+	char buf[10];
+
+	if (cr_uid == 0 && cr_gid == 0)
+		return true;
+
+	if (fstat(fd, &st)) {
+		pr_perror("Can't stat file");
+		return false;
+	}
+
+	if (!(st.st_mode & CR_FD_PERM)) {
+		pr_err("File mode %s != %s\n", mode_str(buf, st.st_mode), mode_str(buf, CR_FD_PERM));
+		return false;
+	}
+
+	if (st.st_uid != 0 || st.st_gid != 0) {
+		pr_err("File uid/gid (%d,%d) != (0,0)\n", st.st_uid, st.st_gid);
+		return false;
+	}
+
+	return true;
+}
-- 
1.9.3



More information about the CRIU mailing list