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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.