[lxc-devel] [lxd/master] cgo: bugfixes

brauner on Github lxc-bot at linuxcontainers.org
Thu Jun 20 10:15:15 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190620/8137fade/attachment-0001.bin>
-------------- next part --------------
From 12f3c4cd4eb86b39151405c9e5a0d935a36ad073 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 20 Jun 2019 11:54:51 +0200
Subject: [PATCH 1/3] checkfeature: remove unused variable

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_checkfeature.go | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lxd/main_checkfeature.go b/lxd/main_checkfeature.go
index 87fced5fd7..bb7abc69a4 100644
--- a/lxd/main_checkfeature.go
+++ b/lxd/main_checkfeature.go
@@ -75,7 +75,6 @@ void is_netnsid_aware(int *hostnetns_fd, int *newnetns_fd)
 {
 	__do_close_prot_errno int sock_fd = -EBADF;
 	int netnsid, ret;
-	struct netns_ifaddrs *ifaddrs;
 
 	*hostnetns_fd = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
 	if (*hostnetns_fd < 0) {

From 8720f079723b2f610068fbf0af3e4aca1831aea6 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 20 Jun 2019 11:56:45 +0200
Subject: [PATCH 2/3] forkmknod: remove unused variables

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_forkmknod.go | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lxd/main_forkmknod.go b/lxd/main_forkmknod.go
index 52d308058b..f7f521f23b 100644
--- a/lxd/main_forkmknod.go
+++ b/lxd/main_forkmknod.go
@@ -98,7 +98,7 @@ static int __do_chowmknod(const char *path, mode_t mode, dev_t dev,
 
 static int __do_chdirchroot(const char *cwd, const char *root)
 {
-	if (cwd && chdir(cwd))
+	if (chdir(cwd))
 		return -1;
 
 	return chroot(root);
@@ -117,7 +117,6 @@ void forkmknod()
 	__do_close_prot_errno int target_fd = -EBADF;
 	__do_free char *p1 = NULL, *p2 = NULL;
 	int ret;
-	ssize_t bytes = 0;
 	char *cur = NULL, *path = NULL, *rootfs_path = NULL,
 		*dir_name_ct = NULL, *dir_name_host = NULL, *base_name = NULL;
 	mode_t mode = 0;
@@ -125,7 +124,7 @@ void forkmknod()
 	pid_t pid = 0;
 	uid_t uid = -1;
 	gid_t gid = -1;
-	char cwd[256], root[256], cwd_path[PATH_MAX];
+	char cwd[256], root[256];
 	struct stat s1, s2;
 	struct statfs sfs1, sfs2;
 

From 8a4e981b2fde1763924172a939c7e80e691b7bce Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 20 Jun 2019 12:14:09 +0200
Subject: [PATCH 3/3] forkmknod: simplify

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_forkmknod.go | 90 ++++++++++++++++++++++---------------------
 1 file changed, 47 insertions(+), 43 deletions(-)

diff --git a/lxd/main_forkmknod.go b/lxd/main_forkmknod.go
index f7f521f23b..8196df0c2e 100644
--- a/lxd/main_forkmknod.go
+++ b/lxd/main_forkmknod.go
@@ -84,7 +84,7 @@ found:
 	return nsid;
 }
 
-static int __do_chowmknod(const char *path, mode_t mode, dev_t dev,
+static int chowmknod(const char *path, mode_t mode, dev_t dev,
 			  uid_t uid, gid_t gid)
 {
 	int ret;
@@ -96,12 +96,16 @@ static int __do_chowmknod(const char *path, mode_t mode, dev_t dev,
 	return chown(path, uid, gid);
 }
 
-static int __do_chdirchroot(const char *cwd, const char *root)
+static int chdirchroot(pid_t pid)
 {
-	if (chdir(cwd))
+	char path[256];
+
+	snprintf(path, sizeof(path), "/proc/%d/cwd", pid);
+	if (chdir(path))
 		return -1;
 
-	return chroot(root);
+	snprintf(path, sizeof(path), "/proc/%d/root", pid);
+	return chroot(path);
 }
 
 static inline bool same_fsinfo(struct stat *s1, struct stat *s2,
@@ -110,21 +114,41 @@ static inline bool same_fsinfo(struct stat *s1, struct stat *s2,
 	return ((sfs1->f_type == sfs2->f_type) && (s1->st_dev == s2->st_dev) && (s1->st_ino == s2->st_ino));
 }
 
+static int stat_statfs(const char *path, struct stat *s, struct statfs *sfs)
+{
+	if (stat(path, s))
+		return -1;
+
+	if (statfs(path, sfs))
+		return -1;
+
+	return 0;
+}
+
+static int fstat_fstatfs(int fd, struct stat *s, struct statfs *sfs)
+{
+	if (fstat(fd, s))
+		return -1;
+
+	if (fstatfs(fd, sfs))
+		return -1;
+
+	return 0;
+}
+
 // Expects command line to be in the form:
 // <PID> <root-uid> <root-gid> <path> <mode> <dev>
 void forkmknod()
 {
 	__do_close_prot_errno int target_fd = -EBADF;
-	__do_free char *p1 = NULL, *p2 = NULL;
+	__do_free char *target_host_dup = NULL;
 	int ret;
-	char *cur = NULL, *path = NULL, *rootfs_path = NULL,
-		*dir_name_ct = NULL, *dir_name_host = NULL, *base_name = NULL;
+	char *cur = NULL, *target = NULL, *target_host = NULL;
 	mode_t mode = 0;
 	dev_t dev = 0;
 	pid_t pid = 0;
 	uid_t uid = -1;
 	gid_t gid = -1;
-	char cwd[256], root[256];
 	struct stat s1, s2;
 	struct statfs sfs1, sfs2;
 
@@ -141,13 +165,11 @@ void forkmknod()
 		_exit(EXIT_FAILURE);
 	}
 
-	// Get the container PID
 	pid = atoi(cur);
-
-	// path to create
-	path = advance_arg(true);
+	target = advance_arg(true);
 	mode = atoi(advance_arg(true));
 	dev = atoi(advance_arg(true));
+	target_host = advance_arg(true);
 
 	uid = get_root_uid(pid);
 	if (uid < 0)
@@ -157,23 +179,18 @@ void forkmknod()
 	if (gid < 0)
 		fprintf(stderr, "No root gid found (%d)\n", gid);
 
-	rootfs_path = advance_arg(true);
-	if (*rootfs_path) {
-		// dirname() can modify its argument
-		p1 = strdup(rootfs_path);
-		if (!p1)
-			_exit(EXIT_FAILURE);
+	// dirname() can modify its argument
+	target_host_dup = strdup(target_host);
+	if (!target_host_dup)
+		_exit(EXIT_FAILURE);
 
-		target_fd = open(dirname(p1), O_PATH | O_RDONLY | O_CLOEXEC);
-	}
+	target_fd = open(dirname(target_host_dup), O_PATH | O_RDONLY | O_CLOEXEC);
 
-	snprintf(cwd, sizeof(cwd), "/proc/%d/cwd", pid);
-	snprintf(root, sizeof(root), "/proc/%d/root", pid);
-	ret = __do_chdirchroot(cwd, root);
+	ret = chdirchroot(pid);
 	if (ret)
 		goto eperm;
 
-	ret = __do_chowmknod(path, mode, dev, uid, gid);
+	ret = chowmknod(target, mode, dev, uid, gid);
 	if (ret) {
 		if (errno == EEXIST) {
 			fprintf(stderr, "%d", errno);
@@ -183,36 +200,23 @@ void forkmknod()
 		_exit(EXIT_SUCCESS);
 	}
 
-	if (!*rootfs_path || target_fd < 0)
-		goto eperm;
-
-	dir_name_ct = dirname(path);
-	ret = stat(dir_name_ct, &s1);
-	if (ret)
+	if (target_fd < 0)
 		goto eperm;
 
-	ret = statfs(dir_name_ct, &sfs1);
+	ret = stat_statfs(dirname(target), &s1, &sfs1);
 	if (ret)
 		goto eperm;
 
-	ret = fstat(target_fd, &s2);
-	if (ret)
-		goto eperm;
-
-	ret = fstatfs(target_fd, &sfs2);
+	ret = fstat_fstatfs(target_fd, &s2, &sfs2);
 	if (ret)
 		goto eperm;
 
 	if (!same_fsinfo(&s1, &s2, &sfs1, &sfs2))
 		goto eperm;
 
-	// basename() can modify its argument
-	p2 = strdup(rootfs_path);
-	if (!p2)
-		goto eperm;
-
-	base_name = basename(p2);
-	ret = mknodat(target_fd, base_name, mode, dev);
+	// basename() can modify its argument so accessing target_host is
+	// invalid from now on.
+	ret = mknodat(target_fd, basename(target_host), mode, dev);
 	if (ret) {
 		if (errno == EEXIST) {
 			fprintf(stderr, "%d", errno);


More information about the lxc-devel mailing list