[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: linux-user: Add option to run `execve`d programs through QEMU
From: |
Noah Goldstein |
Subject: |
Re: linux-user: Add option to run `execve`d programs through QEMU |
Date: |
Tue, 5 Nov 2024 17:54:31 -0600 |
On Tue, Nov 5, 2024 at 5:48 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
>
> On Tue, Nov 5, 2024 at 5:37 AM Richard Henderson
> <richard.henderson@linaro.org> wrote:
> >
> > On 10/30/24 14:10, Noah Goldstein wrote:
> > > The new option '-qemu-children' makes it so that on `execve` the child
> > > process will be launch by the same `qemu` executable that is currently
> > > running along with its current commandline arguments.
> > >
> > > The motivation for the change is to make it so that plugins running
> > > through `qemu` can continue to run on children. Why not just
> > > `binfmt`?: Plugins can be desirable regardless of system/architecture
> > > emulation, and can sometimes be useful for elf files that can run
> > > natively. Enabling `binfmt` for all natively runnable elf files may
> > > not be desirable.
> > >
> > > Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
> > > ---
> > > linux-user/main.c | 21 ++++++
> > > linux-user/syscall.c | 21 ++++--
> > > linux-user/user-internals.h | 4 ++
> > > tests/tcg/multiarch/Makefile.target | 8 +++
> > > .../linux/linux-execve-qemu-children.c | 68 +++++++++++++++++++
> > > 5 files changed, 117 insertions(+), 5 deletions(-)
> > > create mode 100644
> > > tests/tcg/multiarch/linux/linux-execve-qemu-children.c
> > >
> > > diff --git a/linux-user/main.c b/linux-user/main.c
> > > index 8143a0d4b0..5e3d41dc2b 100644
> > > --- a/linux-user/main.c
> > > +++ b/linux-user/main.c
> > > @@ -81,6 +81,10 @@ unsigned long mmap_min_addr;
> > > uintptr_t guest_base;
> > > bool have_guest_base;
> > >
> > > +bool qemu_dup_for_children;
> > > +int qemu_argc;
> > > +char **qemu_argv;
> > > +
> > > /*
> > > * Used to implement backwards-compatibility for the `-strace`, and
> > > * QEMU_STRACE options. Without this, the QEMU_LOG can be overwritten by
> > > @@ -451,6 +455,11 @@ static void handle_arg_jitdump(const char *arg)
> > > perf_enable_jitdump();
> > > }
> > >
> > > +static void handle_arg_qemu_children(const char *arg)
> > > +{
> > > + qemu_dup_for_children = true;
> > > +}
> > > +
> > > static QemuPluginList plugins = QTAILQ_HEAD_INITIALIZER(plugins);
> > >
> > > #ifdef CONFIG_PLUGIN
> > > @@ -526,6 +535,10 @@ static const struct qemu_argument arg_table[] = {
> > > "", "Generate a /tmp/perf-${pid}.map file for perf"},
> > > {"jitdump", "QEMU_JITDUMP", false, handle_arg_jitdump,
> > > "", "Generate a jit-${pid}.dump file for perf"},
> > > + {"qemu-children",
> > > + "QEMU_CHILDREN", false, handle_arg_qemu_children,
> > > + "", "Run child processes (created with execve) with qemu "
> > > + "(as instantiated for the parent)"},
> > > {NULL, NULL, false, NULL, NULL, NULL}
> > > };
> > >
> > > @@ -729,6 +742,14 @@ int main(int argc, char **argv, char **envp)
> > >
> > > optind = parse_args(argc, argv);
> > >
> > > + if (qemu_dup_for_children) {
> > > + qemu_argc = optind;
> > > + qemu_argv = g_new0(char *, qemu_argc);
> > > + for (i = 0; i < optind; ++i) {
> > > + qemu_argv[i] = strdup(argv[i]);
> >
> > g_strdup.
> ack
> >
> > > + bool through_qemu = dirfd == AT_FDCWD && qemu_dup_for_children;
> >
> > Why is this limited to AT_FDCWD? Why not for execvat too?
> >
>
> We could, initially it was because AFAICT qemu doesn't support executing a
> program relative to another dir, but it would be simple enough to just join
> the relative program path and path dirfd points to.
>
> Want me to add support?
> > > @@ -8628,9 +8631,16 @@ static int do_execv(CPUArchState *cpu_env, int
> > > dirfd,
> > > }
> > >
> > > const char *exe = p;
> > > - if (is_proc_myself(p, "exe")) {
> > > + if (through_qemu) {
> > > + int i;
> > > + for (i = 0; i < argp_offset; ++i) {
> > > + argp[i] = qemu_argv[i];
> > > + }
> > > + exe = qemu_argv[0];
> > > + } else if (is_proc_myself(p, "exe")) {
> > > exe = exec_path;
> > > }
> > > +
> >
> > You still need to handle is_proc_myself, for the guest binary.
Would this by handled by basically do:
```
if (is_proc_myself(p, "exe")) {
exe = exec_path;
if (through_qemu)
argp[argp_offset] = exec_path;
}
```
Or am I missing something?
> >
> > I wonder if those two cases are related. Do we need to also add an
> > argument so that we
> > can pass the executable to the next qemu via file descriptor? I.e. execvat
> > becomes
> >
> > f = openat()
> > execv(qemu, "-execfd", f)
> >
> > and is_proc_myself uses execfd, which we already have open.
How does passing a fd from one process to another work?
> >
> >
> > r~
- Re: linux-user: Add option to run `execve`d programs through QEMU, Richard Henderson, 2024/11/05
- Re: linux-user: Add option to run `execve`d programs through QEMU, Noah Goldstein, 2024/11/05
- Re: linux-user: Add option to run `execve`d programs through QEMU,
Noah Goldstein <=
- Re: linux-user: Add option to run `execve`d programs through QEMU, Richard Henderson, 2024/11/06
- Re: linux-user: Add option to run `execve`d programs through QEMU, Noah Goldstein, 2024/11/06
- Re: linux-user: Add option to run `execve`d programs through QEMU, Richard Henderson, 2024/11/06
- Re: linux-user: Add option to run `execve`d programs through QEMU, Noah Goldstein, 2024/11/06
- Re: linux-user: Add option to run `execve`d programs through QEMU, Noah Goldstein, 2024/11/06
- Re: linux-user: Add option to run `execve`d programs through QEMU, Richard Henderson, 2024/11/06
- Re: linux-user: Add option to run `execve`d programs through QEMU, Noah Goldstein, 2024/11/06
- Re: linux-user: Add option to run `execve`d programs through QEMU, Noah Goldstein, 2024/11/06
- Re: linux-user: Add option to run `execve`d programs through QEMU, Richard Henderson, 2024/11/07
- Re: linux-user: Add option to run `execve`d programs through QEMU, Richard Henderson, 2024/11/07