[lxc-devel] [lxc/master] conf: copy mountinfo for remount_all_slave()

brauner on Github lxc-bot at linuxcontainers.org
Mon Jun 4 10:52:47 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 621 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180604/7b1076f9/attachment.bin>
-------------- next part --------------
From 918c8bdb2dc278528ddb7b2d043979c172ea6e93 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 4 Jun 2018 12:49:05 +0200
Subject: [PATCH] conf: copy mountinfo for remount_all_slave()

While a container reads mountinfo from proc fs, the mountinfo can be changed by
the kernel anytime. This has caused critical issues on some devices.

Signed-off-by: Donghwa Jeong dh48.jeong at samsung.com
Reported-by: Donghwa Jeong dh48.jeong at samsung.com
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/conf.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 05d58081e..f16fdaf50 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -43,6 +43,7 @@
 #include <sys/mount.h>
 #include <sys/param.h>
 #include <sys/prctl.h>
+#include <sys/sendfile.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
@@ -3178,14 +3179,56 @@ void tmp_proc_unmount(struct lxc_conf *lxc_conf)
 /* Walk /proc/mounts and change any shared entries to slave. */
 void remount_all_slave(void)
 {
+	int memfd, mntinfo_fd;
+	ssize_t copied;
 	FILE *f;
 	size_t len = 0;
 	char *line = NULL;
 
-	f = fopen("/proc/self/mountinfo", "r");
+	mntinfo_fd = open("/proc/self/mountinfo", O_RDONLY | O_CLOEXEC);
+	if (mntinfo_fd < 0)
+		return;
+
+	memfd = memfd_create(".lxc_mountinfo", MFD_CLOEXEC);
+	if (memfd < 0) {
+		char template[] = P_tmpdir "/.lxc_mountinfo_XXXXXX";
+
+		if (errno != ENOSYS) {
+			close(mntinfo_fd);
+			WARN("Failed to create temporary in-memory file");
+			return;
+		}
+
+		memfd = lxc_make_tmpfile(template, true);
+	}
+	if (memfd < 0) {
+		close(mntinfo_fd);
+		WARN("Failed to create temporary file");
+		return;
+	}
+
+#define __LXC_SENDFILE_MAX 0x7ffff000 /* maximum number of bytes sendfile can handle */
+again:
+	copied = sendfile(memfd, mntinfo_fd, NULL, __LXC_SENDFILE_MAX);
+	if (copied < 0) {
+		if (errno == EINTR)
+			goto again;
+
+		close(mntinfo_fd);
+		close(memfd);
+		WARN("Failed to copy \"/proc/self/mountinfo\"");
+		return;
+	}
+	close(mntinfo_fd);
+
+	/* After a successful fdopen() memfd will be closed when calling
+	 * fclose(f). Calling close(memfd) afterwards is undefined.
+	 */
+	f = fdopen(memfd, "r");
 	if (!f) {
-		SYSERROR("Failed to open \"/proc/self/mountinfo\" to mark all shared");
-		ERROR("Continuing container startup...");
+		WARN("Failed to open copy of \"/proc/self/mountinfo\" to mark "
+		     "all shared. Continuing");
+		close(memfd);
 		return;
 	}
 
@@ -3214,6 +3257,7 @@ void remount_all_slave(void)
 	}
 	fclose(f);
 	free(line);
+	TRACE("Remounted all mount table entries as MS_SLAVE");
 }
 
 static int lxc_execute_bind_init(struct lxc_handler *handler)


More information about the lxc-devel mailing list