[lxc-devel] [lxd/master] forksyscall: mknod fixes
brauner on Github
lxc-bot at linuxcontainers.org
Mon Jul 15 11:53:44 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/20190715/45e991ce/attachment-0001.bin>
-------------- next part --------------
From 048dc04614931c3fc58ec7e4a8756f892eb870d0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jul 2019 13:35:13 +0200
Subject: [PATCH 1/3] forksyscall: avoid calling close on garbage fd
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/main_forksyscall.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/main_forksyscall.go b/lxd/main_forksyscall.go
index f40e87e196..1c07bc0cd7 100644
--- a/lxd/main_forksyscall.go
+++ b/lxd/main_forksyscall.go
@@ -102,7 +102,7 @@ static int fstat_fstatfs(int fd, struct stat *s, struct statfs *sfs)
// <PID> <root-uid> <root-gid> <path> <mode> <dev>
static void forkmknod()
{
- __do_close_prot_errno int target_fd = -EBADF, host_target_fd;
+ __do_close_prot_errno int target_fd = -EBADF, host_target_fd = -EBADF;
int ret;
char *cur = NULL, *target = NULL, *target_host = NULL;
char cwd[256];
From 2f7960044384a2bd78c955d58a10e4076f7546e6 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jul 2019 13:38:51 +0200
Subject: [PATCH 2/3] forksyscall: s/target_fd/cwd_fd/g
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/main_forksyscall.go | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lxd/main_forksyscall.go b/lxd/main_forksyscall.go
index 1c07bc0cd7..7cd6e9b3f4 100644
--- a/lxd/main_forksyscall.go
+++ b/lxd/main_forksyscall.go
@@ -102,10 +102,10 @@ static int fstat_fstatfs(int fd, struct stat *s, struct statfs *sfs)
// <PID> <root-uid> <root-gid> <path> <mode> <dev>
static void forkmknod()
{
- __do_close_prot_errno int target_fd = -EBADF, host_target_fd = -EBADF;
+ __do_close_prot_errno int cwd_fd = -EBADF, host_target_fd = -EBADF;
int ret;
char *cur = NULL, *target = NULL, *target_host = NULL;
- char cwd[256];
+ char path[PATH_MAX];
mode_t mode = 0;
dev_t dev = 0;
pid_t pid = 0;
@@ -125,9 +125,9 @@ static void forkmknod()
gid = atoi(advance_arg(true));
chk_perm_only = atoi(advance_arg(true));
- snprintf(cwd, sizeof(cwd), "/proc/%d/cwd", pid);
- target_fd = open(cwd, O_PATH | O_RDONLY | O_CLOEXEC);
- if (target_fd < 0) {
+ snprintf(path, sizeof(path), "/proc/%d/cwd", pid);
+ cwd_fd = open(path, O_PATH | O_RDONLY | O_CLOEXEC);
+ if (cwd_fd < 0) {
fprintf(stderr, "%d", ENOANO);
_exit(EXIT_FAILURE);
}
@@ -174,7 +174,7 @@ static void forkmknod()
_exit(EXIT_FAILURE);
}
- ret = fstat_fstatfs(target_fd, &s2, &sfs2);
+ ret = fstat_fstatfs(cwd_fd, &s2, &sfs2);
if (ret) {
fprintf(stderr, "%d", ENOANO);
_exit(EXIT_FAILURE);
@@ -203,7 +203,7 @@ static void forkmknod()
// basename() can modify its argument so accessing target_host is
// invalid from now on.
- ret = mknodat(target_fd, target, mode, dev);
+ ret = mknodat(cwd_fd, target, mode, dev);
if (ret) {
fprintf(stderr, "%d", errno);
_exit(EXIT_FAILURE);
From 49fe45596b7b39eae57c3757d695618c0bc0362b Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jul 2019 13:40:11 +0200
Subject: [PATCH 3/3] forksyscall: add chdirchroot()
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/main_forksyscall.go | 38 ++++++++++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/lxd/main_forksyscall.go b/lxd/main_forksyscall.go
index 7cd6e9b3f4..35d134d706 100644
--- a/lxd/main_forksyscall.go
+++ b/lxd/main_forksyscall.go
@@ -98,13 +98,28 @@ static int fstat_fstatfs(int fd, struct stat *s, struct statfs *sfs)
return 0;
}
+static bool chdirchroot(pid_t pid)
+{
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path), "/proc/%d/cwd", pid);
+ if (chdir(path))
+ return false;
+
+ snprintf(path, sizeof(path), "/proc/%d/root", pid);
+ if (chroot(path))
+ return false;
+
+ return true;
+}
+
// Expects command line to be in the form:
// <PID> <root-uid> <root-gid> <path> <mode> <dev>
static void forkmknod()
{
__do_close_prot_errno int cwd_fd = -EBADF, host_target_fd = -EBADF;
int ret;
- char *cur = NULL, *target = NULL, *target_host = NULL;
+ char *cur = NULL, *target = NULL, *target_dir = NULL, *target_host = NULL;
char path[PATH_MAX];
mode_t mode = 0;
dev_t dev = 0;
@@ -125,7 +140,15 @@ static void forkmknod()
gid = atoi(advance_arg(true));
chk_perm_only = atoi(advance_arg(true));
- snprintf(path, sizeof(path), "/proc/%d/cwd", pid);
+ if (*target == '/') {
+ // user has specified an absolute path
+ snprintf(path, sizeof(path), "%s", target);
+ target_dir = dirname(path);
+ } else {
+ // user has specified a relative path
+ snprintf(path, sizeof(path), "/proc/%d/cwd", pid);
+ target_dir = path;
+ }
cwd_fd = open(path, O_PATH | O_RDONLY | O_CLOEXEC);
if (cwd_fd < 0) {
fprintf(stderr, "%d", ENOANO);
@@ -138,7 +161,15 @@ static void forkmknod()
_exit(EXIT_FAILURE);
}
- (void)dosetns(pid, "mnt");
+ if (dosetns(pid, "mnt")) {
+ fprintf(stderr, "%d", ENOANO);
+ _exit(EXIT_FAILURE);
+ }
+
+ if (chdirchroot(pid)) {
+ fprintf(stderr, "%d", ENOANO);
+ _exit(EXIT_FAILURE);
+ }
caps = cap_get_pid(pid);
if (!caps) {
@@ -208,7 +239,6 @@ static void forkmknod()
fprintf(stderr, "%d", errno);
_exit(EXIT_FAILURE);
}
-
}
void forksyscall()
More information about the lxc-devel
mailing list