From: "Alex Bennée" <alex.bennee@linaro.org>
To: YAMAMOTO Takashi <yamamoto@midokura.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [PATCH 0/5] linux-user changes to run docker
Date: Mon, 24 May 2021 18:45:18 +0100 [thread overview]
Message-ID: <87cztg3tv0.fsf@linaro.org> (raw)
In-Reply-To: <20210524045412.15152-1-yamamoto@midokura.com>
[-- Attachment #1: Type: text/plain, Size: 616 bytes --]
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:
[-- Attachment #2: /proc/self test --]
[-- Type: text/x-diff, Size: 3695 bytes --]
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
[-- Attachment #3: Type: text/plain, Size: 644 bytes --]
> 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.
[-- Attachment #4: glib-ify is_proc_self --]
[-- Type: text/x-diff, Size: 2841 bytes --]
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
[-- Attachment #5: Type: text/plain, Size: 23 bytes --]
--
Alex Bennée
next prev parent reply other threads:[~2021-05-24 17:50 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-24 4:54 [PATCH 0/5] linux-user changes to run docker YAMAMOTO Takashi
2021-05-24 4:54 ` [PATCH 1/5] linux-user: handle /proc/self/exe for execve YAMAMOTO Takashi
2021-05-24 10:50 ` Alex Bennée
2021-05-24 22:54 ` Takashi Yamamoto
2021-05-24 4:54 ` [PATCH 2/5] linux-uesr: make exec_path realpath YAMAMOTO Takashi
2021-05-24 10:55 ` Alex Bennée
2021-05-24 22:59 ` Takashi Yamamoto
2021-05-26 1:42 ` Takashi Yamamoto
2021-05-24 4:54 ` [PATCH 3/5] linux-user: Fix the execfd case of /proc/self/exe open YAMAMOTO Takashi
2021-05-24 4:54 ` [PATCH 4/5] linux-user: dup the execfd on start up YAMAMOTO Takashi
2021-05-24 4:54 ` [PATCH 5/5] linux-user: Implement pivot_root YAMAMOTO Takashi
2021-05-25 20:21 ` Laurent Vivier
2021-05-26 0:50 ` Takashi Yamamoto
2021-05-24 17:45 ` Alex Bennée [this message]
2021-05-24 23:22 ` [PATCH 0/5] linux-user changes to run docker Takashi Yamamoto
2021-05-27 1:44 ` Takashi Yamamoto
2021-05-27 13:08 ` Alex Bennée
2021-05-31 2:45 ` Takashi Yamamoto
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87cztg3tv0.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=yamamoto@midokura.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).