Re: [PATCH] Fix proc:::exec args[0]
Kris Van Hees <[email protected]>
| Newsgroups | dev.linux.lists.dtrace |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Oct 02, 2025 at 01:05:58AM -0400, [email protected] wrote: > From: Eugene Loh <[email protected]> > > Reported-by: Kris Van Hees <[email protected]> > Signed-off-by: Eugene Loh <[email protected]> Reviewed-by: Kris Van Hees <[email protected]> > --- > libdtrace/dt_prov_proc.c | 12 ++++++ > test/unittest/proc/tst.exec-execve.r | 4 ++ > test/unittest/proc/tst.exec-execve.sh | 52 ++++++++++++++++++++++++ > test/unittest/proc/tst.exec-execveat.r | 4 ++ > test/unittest/proc/tst.exec-execveat.sh | 54 +++++++++++++++++++++++++ > 5 files changed, 126 insertions(+) > create mode 100644 test/unittest/proc/tst.exec-execve.r > create mode 100755 test/unittest/proc/tst.exec-execve.sh > create mode 100644 test/unittest/proc/tst.exec-execveat.r > create mode 100755 test/unittest/proc/tst.exec-execveat.sh > > diff --git a/libdtrace/dt_prov_proc.c b/libdtrace/dt_prov_proc.c > index 05ad66346..f7e46a5af 100644 > --- a/libdtrace/dt_prov_proc.c > +++ b/libdtrace/dt_prov_proc.c > @@ -118,6 +118,18 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl) > emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(1))); > emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, exitlbl)); > emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0)); > + } else if (strcmp(prp->desc->prb, "exec") == 0) { > + dt_probe_t *uprp = pcb->pcb_parent_probe; > + > + /* > + * If the underlying probe is syscall:vmlinux:execve:entry, > + * then the arg0 is already right. If it is execveat, we have > + * to copy arg1 to arg0. > + */ > + if (strcmp(uprp->desc->fun, "execveat") == 0) { > + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(1))); > + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0)); > + } > } else if (strcmp(prp->desc->prb, "exit") == 0) { > ctf_file_t *cfp = dtp->dt_shared_ctf; > ctf_id_t type; > diff --git a/test/unittest/proc/tst.exec-execve.r b/test/unittest/proc/tst.exec-execve.r > new file mode 100644 > index 000000000..09791d5b0 > --- /dev/null > +++ b/test/unittest/proc/tst.exec-execve.r > @@ -0,0 +1,4 @@ > +execve bogus_direc/bogus_exec > +proc:::exec bogus_direc/bogus_exec > +exec > + > diff --git a/test/unittest/proc/tst.exec-execve.sh b/test/unittest/proc/tst.exec-execve.sh > new file mode 100755 > index 000000000..d3f84e0d2 > --- /dev/null > +++ b/test/unittest/proc/tst.exec-execve.sh > @@ -0,0 +1,52 @@ > +#!/bin/bash > +# > +# Oracle Linux DTrace. > +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. > +# Licensed under the Universal Permissive License v 1.0 as shown at > +# http://oss.oracle.com/licenses/upl. > +# > +# This script tests that the proc:::exec probe fires for execve() and > +# produces the correct probe arg. > + > +dtrace=$1 > + > +DIRNAME="$tmpdir/exec-execve.$$.$RANDOM" > +mkdir -p $DIRNAME > +cd $DIRNAME > + > +cat << EOF > parent.c > +#include <stdio.h> > +#include <unistd.h> > + > +int main(int c, char **v) { > + char *argv[] = { "bogus_exec", NULL }; > + char *envp[] = { NULL }; > + int rc; > + > + printf("exec\n"); > + rc = execve("bogus_direc/bogus_exec", argv, envp); > + > + return 0; > +} > +EOF > + > +${CC} -o parent.x parent.c > + > +$dtrace $dt_flags -qn ' > +BEGIN { dtpid = pid; } > +proc:::exec > +/ppid == dtpid && execname == "parent.x"/ > +{ > + printf("proc:::exec %s\n", args[0]); > +} > +syscall::execve:entry > +/ppid == dtpid && execname == "parent.x"/ > +{ > + printf("execve %s\n", stringof(arg0)); > +}' -c ./parent.x > +if [ $? -ne 0 ]; then > + echo ERROR > + exit 1 > +fi > + > +exit 0 > diff --git a/test/unittest/proc/tst.exec-execveat.r b/test/unittest/proc/tst.exec-execveat.r > new file mode 100644 > index 000000000..696300e0e > --- /dev/null > +++ b/test/unittest/proc/tst.exec-execveat.r > @@ -0,0 +1,4 @@ > +execveat bogus_direc/bogus_exec > +proc:::exec bogus_direc/bogus_exec > +exec > + > diff --git a/test/unittest/proc/tst.exec-execveat.sh b/test/unittest/proc/tst.exec-execveat.sh > new file mode 100755 > index 000000000..db68a5043 > --- /dev/null > +++ b/test/unittest/proc/tst.exec-execveat.sh > @@ -0,0 +1,54 @@ > +#!/bin/bash > +# > +# Oracle Linux DTrace. > +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. > +# Licensed under the Universal Permissive License v 1.0 as shown at > +# http://oss.oracle.com/licenses/upl. > +# > +# This script tests that the proc:::exec probe fires for execveat() and > +# produces the correct probe arg. > + > +dtrace=$1 > + > +DIRNAME="$tmpdir/exec-execveat.$$.$RANDOM" > +mkdir -p $DIRNAME > +cd $DIRNAME > + > +cat << EOF > parent.c > +#include <stdio.h> > +#include <linux/fcntl.h> /* Definition of AT_* constants */ > +#define __USE_GNU /* so unistd.h will find execveat */ > +#include <unistd.h> > + > +int main(int c, char **v) { > + char *argv[] = { "bogus_exec", NULL }; > + char *envp[] = { NULL }; > + int rc; > + > + printf("exec\n"); > + rc = execveat(AT_FDCWD, "bogus_direc/bogus_exec", argv, envp, 0); > + > + return 0; > +} > +EOF > + > +${CC} -o parent.x parent.c > + > +$dtrace $dt_flags -qn ' > +BEGIN { dtpid = pid; } > +proc:::exec > +/ppid == dtpid && execname == "parent.x"/ > +{ > + printf("proc:::exec %s\n", args[0]); > +} > +syscall::execveat:entry > +/ppid == dtpid && execname == "parent.x"/ > +{ > + printf("execveat %s\n", stringof(arg1)); > +}' -c ./parent.x > +if [ $? -ne 0 ]; then > + echo ERROR > + exit 1 > +fi > + > +exit 0 > -- > 2.47.3 >