[lxc-devel] [lxcfs/master] lxcfs: fix shared library reload

brauner on Github lxc-bot at linuxcontainers.org
Fri Mar 13 10:40:05 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 365 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200313/70316b27/attachment.bin>
-------------- next part --------------
From 3326c17e2686df9d543f0b4b47665e8dd991e170 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 13 Mar 2020 11:12:14 +0100
Subject: [PATCH 1/2] tree-wide: add missing O_CLOEXEC

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/bindings.c | 4 ++--
 src/lxcfs.c    | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/bindings.c b/src/bindings.c
index 45555d5..4eadbe0 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -525,12 +525,12 @@ static int pivot_enter()
 {
 	__do_close_prot_errno int oldroot = -EBADF, newroot = -EBADF;
 
-	oldroot = open("/", O_DIRECTORY | O_RDONLY);
+	oldroot = open("/", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
 	if (oldroot < 0)
 		return log_error_errno(-1, errno,
 				       "Failed to open old root for fchdir");
 
-	newroot = open(ROOTDIR, O_DIRECTORY | O_RDONLY);
+	newroot = open(ROOTDIR, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
 	if (newroot < 0)
 		return log_error_errno(-1, errno,
 				       "Failed to open new root for fchdir");
diff --git a/src/lxcfs.c b/src/lxcfs.c
index b614f48..80a8b65 100644
--- a/src/lxcfs.c
+++ b/src/lxcfs.c
@@ -1035,7 +1035,7 @@ static int set_pidfile(char *pidfile)
 		fl.l_len	= 0,
 	};
 
-	fd = open(pidfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+	fd = open(pidfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | O_CLOEXEC);
 	if (fd < 0)
 		return log_error(-1, "Could not open pidfile %s: %m", pidfile);
 

From de69569b541fb7cb2f9bde65b88b444543dec0b8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 13 Mar 2020 11:34:37 +0100
Subject: [PATCH 2/2] bindings: handle current working directory on upgrade

Recenly I've made failures to run the constructor or destructor fatal.
Mostly, because we can't guarantee correct functionality if they fail.
In fact we can't do anything useful at all (Maybe I can come up with
something more useful soon.)
In any case, this surfaced a bug where on systems that replace/delete
the current workding directory of lxcfs will cause the constructor to
crash on reload because the path that getcwd() returns does not exist
anymore. Fix this by always escaping to root after the construtor has
run but also make it optional in case someone is messing with chroot()s
or other things.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/bindings.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/src/bindings.c b/src/bindings.c
index 4eadbe0..26ff9bf 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -717,11 +717,10 @@ static bool cgfs_setup_controllers(void)
 
 static void __attribute__((constructor)) lxcfs_init(void)
 {
-	__do_close_prot_errno int init_ns = -EBADF, pidfd = -EBADF;
+	__do_close_prot_errno int init_ns = -EBADF, root_fd = -EBADF,
+				  pidfd = -EBADF;
 	int i = 0;
 	pid_t pid;
-	char *cret;
-	char cwd[MAXPATHLEN];
 
 	lxcfs_info("Running constructor %s", __func__);
 
@@ -735,10 +734,6 @@ static void __attribute__((constructor)) lxcfs_init(void)
 	if (init_ns < 0)
 		log_exit("Failed to preserve initial mount namespace");
 
-	cret = getcwd(cwd, MAXPATHLEN);
-	if (!cret)
-		log_exit("%s - Could not retrieve current working directory", strerror(errno));
-
 	/* This function calls unshare(CLONE_NEWNS) our initial mount namespace
 	 * to privately mount lxcfs cgroups. */
 	if (!cgfs_setup_controllers())
@@ -747,9 +742,6 @@ static void __attribute__((constructor)) lxcfs_init(void)
 	if (setns(init_ns, 0) < 0)
 		log_exit("%s - Failed to switch back to initial mount namespace", strerror(errno));
 
-	if (!cret || chdir(cwd) < 0)
-		log_exit("%s - Could not change back to original working directory", strerror(errno));
-
 	if (!init_cpuview())
 		log_exit("Failed to init CPU view");
 
@@ -773,6 +765,15 @@ static void __attribute__((constructor)) lxcfs_init(void)
 	lxcfs_info("api_extensions:");
 	for (i = 0; i < nr_api_extensions; i++)
 		lxcfs_info("- %s", api_extensions[i]);
+
+	root_fd = open("/", O_PATH | O_CLOEXEC);
+	if (root_fd < 0) {
+		lxcfs_error("%s - Failed to open root directory", strerror(errno));
+		return;
+	}
+
+	if (fchdir(root_fd) < 0)
+		lxcfs_error("%s - Failed to change to root directory", strerror(errno));
 }
 
 static void __attribute__((destructor)) lxcfs_exit(void)


More information about the lxc-devel mailing list