qemu-devel
[Top][All Lists]
Advanced

[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:48:06 -0600

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.
>
> 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.
>
>
> r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]