[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 0/5] linux-user changes to run docker
From: |
Alex Bennée |
Subject: |
Re: [PATCH 0/5] linux-user changes to run docker |
Date: |
Mon, 24 May 2021 18:45:18 +0100 |
User-agent: |
mu4e 1.5.13; emacs 28.0.50 |
YAMAMOTO Takashi <yamamoto@midokura.com> writes:
> These patches, along with a few more hacks [1] I didn't include
> in this patchset, allowed me to run arm64 and armv7 version of
> dind image on amd64.
>
> [1] https://github.com/yamt/qemu/tree/linux-user-for-docker
Might be worth posting those patches next time (even if they have a RFC
or !MERGE in the title for now). I had a little noodle around with
testing and quickly found a few holes. It would be nice if we could have
a unit test to cover these various bits as I fear it will easily break
again. Feel free to use the following as a basis if you want:
>From 5d331e84f3e8763921a619647a46bc8b4c9f3207 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Mon, 24 May 2021 10:49:55 +0100
Subject: [PATCH 1/2] tests/tcg: simple test for /proc/self behaviour
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
tests/tcg/multiarch/self.c | 114 +++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
create mode 100644 tests/tcg/multiarch/self.c
diff --git a/tests/tcg/multiarch/self.c b/tests/tcg/multiarch/self.c
new file mode 100644
index 0000000000..f6ea145d16
--- /dev/null
+++ b/tests/tcg/multiarch/self.c
@@ -0,0 +1,114 @@
+/*
+ * /proc/self checks
+ *
+ * Copyright (c) 2021 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#define _GNU_SOURCE
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+
+static void error1(const char *filename, int line, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d: ", filename, line);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(1);
+}
+
+static int __chk_error(const char *filename, int line, int ret)
+{
+ if (ret < 0) {
+ error1(filename, line, "%m (ret=%d, errno=%d/%s)",
+ ret, errno, strerror(errno));
+ }
+ return ret;
+}
+
+#define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__)
+
+#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
+
+#define PATH_MAX 1024
+
+static void check_self_exe(struct stat *self)
+{
+ struct stat statbuf;
+ struct stat linkbuf;
+ chk_error(stat("/proc/self/exe", &statbuf));
+ chk_error(lstat("/proc/self/exe", &linkbuf));
+ assert(statbuf.st_ino != linkbuf.st_ino);
+ assert(statbuf.st_ino == self->st_ino);
+}
+
+static void check_mypid(struct stat *self)
+{
+ pid_t me = getpid();
+ char path[PATH_MAX];
+ struct stat statbuf;
+ struct stat linkbuf;
+
+ snprintf(&path[0], PATH_MAX, "/proc/%d/exe", me);
+
+ chk_error(stat(path, &statbuf));
+ chk_error(lstat(path, &linkbuf));
+ assert(statbuf.st_ino != linkbuf.st_ino);
+ assert(statbuf.st_ino == self->st_ino);
+}
+
+static void check_noncanon(struct stat *self)
+{
+ struct stat statbuf;
+ int fd_slash, fd_dot;
+
+ fd_slash = openat(AT_FDCWD, "/proc///self/exe", O_PATH);
+ chk_error(fstat(fd_slash, &statbuf));
+ assert(statbuf.st_ino == self->st_ino);
+ close(fd_slash);
+
+ fd_dot = openat(AT_FDCWD, "/proc/./self/exe", O_PATH);
+ chk_error(fstat(fd_dot, &statbuf));
+ assert(statbuf.st_ino == self->st_ino);
+ close(fd_dot);
+}
+
+int main(int argc, char **argv)
+{
+ struct stat self;
+
+ chk_error(stat(argv[0], &self));
+ printf("I am %s (%d/%lu)\n", argv[0], argc,
+ (long unsigned int) self.st_ino);
+
+ check_self_exe(&self);
+ check_mypid(&self);
+ check_noncanon(&self);
+
+#if 0
+ if (argc == 2) {
+ printf("I think I execve'd myself\n");
+ } else {
+ char *new_argv[3] = { argv[0], "again", NULL };
+ chk_error(execve("/proc/self/exe", new_argv, NULL));
+ /* should never return */
+ return -1;
+ }
+#endif
+
+ return 0;
+}
base-commit: d36f3ecdc70af8941053cca8347daca757be2865
--
2.20.1
> You can find my test setup here:
> https://github.com/yamt/garbage/tree/master/binfmt-aarch64-install
>
> YAMAMOTO Takashi (5):
> linux-user: handle /proc/self/exe for execve
> linux-uesr: make exec_path realpath
> linux-user: Fix the execfd case of /proc/self/exe open
> linux-user: dup the execfd on start up
> linux-user: Implement pivot_root
>
> linux-user/main.c | 14 +++++++++++++-
> linux-user/qemu.h | 2 ++
> linux-user/syscall.c | 43 ++++++++++++++++++++++++++++++++++++++++---
> 3 files changed, 55 insertions(+), 4 deletions(-)
I also had a go at cleaning up is_proc_self and Daniel greatly
simplified it.
>From fe342309661e3fe8b9e192e6df6ef84267207dac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Mon, 24 May 2021 12:19:18 +0100
Subject: [PATCH 2/2] linux-user: glib-ify is_proc_myself
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
For the cost of a couple of heap allocations we can reduce the code
complexity to a couple of string compares. While we are at it make the
function a bool return and fixup the fake_open function prototypes.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
v2
- use danpb's suggestion
---
linux-user/syscall.c | 31 +++++++------------------------
1 file changed, 7 insertions(+), 24 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e739921e86..8af48b5f1f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7987,33 +7987,16 @@ static int open_self_auxv(void *cpu_env, int fd)
return 0;
}
-static int is_proc_myself(const char *filename, const char *entry)
-{
- if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
- filename += strlen("/proc/");
- if (!strncmp(filename, "self/", strlen("self/"))) {
- filename += strlen("self/");
- } else if (*filename >= '1' && *filename <= '9') {
- char myself[80];
- snprintf(myself, sizeof(myself), "%d/", getpid());
- if (!strncmp(filename, myself, strlen(myself))) {
- filename += strlen(myself);
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- if (!strcmp(filename, entry)) {
- return 1;
- }
- }
- return 0;
+static bool is_proc_myself(const char *filename, const char *entry)
+{
+ g_autofree char *procself = g_strdup_printf("/proc/self/%s", entry);
+ g_autofree char *procpid = g_strdup_printf("/proc/%d/%s", getpid(), entry);
+ return g_str_equal(filename, procself) || g_str_equal(filename, procpid);
}
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) || \
defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA)
-static int is_proc(const char *filename, const char *entry)
+static bool is_proc(const char *filename, const char *entry)
{
return strcmp(filename, entry) == 0;
}
@@ -8097,7 +8080,7 @@ static int do_openat(void *cpu_env, int dirfd, const char
*pathname, int flags,
struct fake_open {
const char *filename;
int (*fill)(void *cpu_env, int fd);
- int (*cmp)(const char *s1, const char *s2);
+ bool (*cmp)(const char *s1, const char *s2);
};
const struct fake_open *fake_open;
static const struct fake_open fakes[] = {
--
2.20.1
--
Alex Bennée
- Re: [PATCH 2/5] linux-uesr: make exec_path realpath, (continued)
[PATCH 1/5] linux-user: handle /proc/self/exe for execve, YAMAMOTO Takashi, 2021/05/24
[PATCH 3/5] linux-user: Fix the execfd case of /proc/self/exe open, YAMAMOTO Takashi, 2021/05/24
[PATCH 4/5] linux-user: dup the execfd on start up, YAMAMOTO Takashi, 2021/05/24
[PATCH 5/5] linux-user: Implement pivot_root, YAMAMOTO Takashi, 2021/05/24
Re: [PATCH 0/5] linux-user changes to run docker,
Alex Bennée <=