[DTrace-devel] [PATCH] cg, test: fix copyinstr() implementation to use a tstring

Eugene Loh eugene.loh at oracle.com
Fri Feb 17 02:57:59 UTC 2023


Reviewed-by: Eugene Loh <eugene.loh at oracle.com>

On 2/16/23 16:31, Kris Van Hees via DTrace-devel wrote:
> Since copyinstr() returns a string, it should be using a temporary
> string like other string functions.  Also, semantics needed fixing to
> apply strsize as an upper limit to the optional size rather than
> triggering a fault if the size is greater than strsize.
>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>   libdtrace/dt_cg.c                             | 23 +++++++-------
>   libdtrace/dt_open.c                           |  2 +-
>   .../funcs/copyinstr/err.D_ALLOCA_SIZE.d       | 26 ----------------
>   .../copyinstr/tst.copyinstr-high-maxsize.d    | 30 +++++++++++++++++++
>   .../copyinstr/tst.copyinstr-high-maxsize.r    |  4 +++
>   5 files changed, 47 insertions(+), 38 deletions(-)
>   delete mode 100644 test/unittest/funcs/copyinstr/err.D_ALLOCA_SIZE.d
>   create mode 100644 test/unittest/funcs/copyinstr/tst.copyinstr-high-maxsize.d
>   create mode 100644 test/unittest/funcs/copyinstr/tst.copyinstr-high-maxsize.r
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index cb284f07..8e767c2f 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -4517,7 +4517,7 @@ dt_cg_subr_copyinstr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
>   	dt_node_t	*size = src->dn_list;
>   	int		maxsize = dtp->dt_options[DTRACEOPT_STRSIZE];
>   	uint_t		lbl_ok = dt_irlist_label(dlp);
> -	uint_t		lbl_badsize = dt_irlist_label(dlp);
> +	uint_t		lbl_oksize = dt_irlist_label(dlp);
>   
>   	TRACE_REGSET("    subr-copyinstr:Begin");
>   
> @@ -4529,15 +4529,19 @@ dt_cg_subr_copyinstr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
>   
>   	dt_cg_node(size, dlp, drp);
>   
> -	emit(dlp,  BPF_BRANCH_IMM(BPF_JSLT, size->dn_reg, 0, lbl_badsize));
> -	emit(dlp,  BPF_BRANCH_IMM(BPF_JGT, size->dn_reg, maxsize, lbl_badsize));
> +	emit(dlp,  BPF_BRANCH_IMM(BPF_JLE, size->dn_reg, maxsize, lbl_oksize));
> +	emit(dlp,  BPF_MOV_IMM(size->dn_reg, maxsize));
> +	emitl(dlp, lbl_oksize,
> +		   BPF_NOP());
>   
> -	if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
> +	/* Allocate a temporary string for the destination (return value). */
> +	dnp->dn_reg = dt_regset_alloc(drp);
> +	if (dnp->dn_reg == -1)
>   		longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> -
> -	/* Allocate scratch space. */
> -	dt_cg_subr_alloca_impl(dnp, size, dlp, drp);
> -	dt_cg_alloca_ptr(dlp, drp, dnp->dn_reg, dnp->dn_reg);
> +	dt_cg_tstring_alloc(yypcb, dnp);
> +	emit(dlp,  BPF_LOAD(BPF_DW, dnp->dn_reg, BPF_REG_FP, DT_STK_DCTX));
> +	emit(dlp,  BPF_LOAD(BPF_DW, dnp->dn_reg, dnp->dn_reg, DCTX_MEM));
> +	emit(dlp,  BPF_ALU64_IMM(BPF_ADD, dnp->dn_reg, dnp->dn_tstring->dn_value));
>   
>   	dt_cg_node(src, dlp, drp);
>   
> @@ -4552,9 +4556,6 @@ dt_cg_subr_copyinstr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
>   	dt_regset_free_args(drp);
>   	emit(dlp,  BPF_BRANCH_IMM(BPF_JSGT, BPF_REG_0, 0, lbl_ok));
>   	dt_cg_probe_error(yypcb, DTRACEFLT_BADADDR, DT_ISREG, src->dn_reg);
> -	emitl(dlp, lbl_badsize,
> -		   BPF_NOP());
> -	dt_cg_probe_error(yypcb, DTRACEFLT_BADSIZE, DT_ISREG, size->dn_reg);
>   	emitl(dlp, lbl_ok,
>   		   BPF_NOP());
>   	dt_regset_free(drp, BPF_REG_0);
> diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
> index a3754a32..8cd861e9 100644
> --- a/libdtrace/dt_open.c
> +++ b/libdtrace/dt_open.c
> @@ -131,7 +131,7 @@ static const dt_ident_t _dtrace_globals[] = {
>   	&dt_idops_func, "void(int)" },
>   { "copyin", DT_IDENT_FUNC, 0, DIF_SUBR_COPYIN, DT_ATTR_STABCMN, DT_VERS_1_0,
>   	&dt_idops_func, "void *(uintptr_t, size_t)" },
> -{ "copyinstr", DT_IDENT_FUNC, 0, DIF_SUBR_COPYINSTR,
> +{ "copyinstr", DT_IDENT_FUNC, DT_IDFLG_DPTR, DIF_SUBR_COPYINSTR,
>   	DT_ATTR_STABCMN, DT_VERS_1_0,
>   	&dt_idops_func, "string(uintptr_t, [size_t])" },
>   { "copyinto", DT_IDENT_FUNC, 0, DIF_SUBR_COPYINTO, DT_ATTR_STABCMN,
> diff --git a/test/unittest/funcs/copyinstr/err.D_ALLOCA_SIZE.d b/test/unittest/funcs/copyinstr/err.D_ALLOCA_SIZE.d
> deleted file mode 100644
> index c9f25721..00000000
> --- a/test/unittest/funcs/copyinstr/err.D_ALLOCA_SIZE.d
> +++ /dev/null
> @@ -1,26 +0,0 @@
> -/*
> - * Oracle Linux DTrace.
> - * Copyright (c) 2022, 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.
> - */
> -
> -/*
> - * ASSERTION: The copyinstr() size must not exceed the (adjusted) scratchsize.
> - *
> - * SECTION: Actions and Subroutines/copyinstr()
> - *	    User Process Tracing/copyin() and copyinstr()
> - */
> -
> -#pragma D option scratchsize=64
> -
> -BEGIN
> -{
> -	copyinstr(0, 65);
> -	exit(0);
> -}
> -
> -ERROR
> -{
> -	exit(1);
> -}
> diff --git a/test/unittest/funcs/copyinstr/tst.copyinstr-high-maxsize.d b/test/unittest/funcs/copyinstr/tst.copyinstr-high-maxsize.d
> new file mode 100644
> index 00000000..7a341640
> --- /dev/null
> +++ b/test/unittest/funcs/copyinstr/tst.copyinstr-high-maxsize.d
> @@ -0,0 +1,30 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2006, 2023, 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.
> + */
> +
> +/*
> + * ASSERTION: It is possible to read a string from userspace addresses.
> + *
> + * SECTION: Actions and Subroutines/copyinstr()
> + *	    User Process Tracing/copyin() and copyinstr() Subroutines
> + */
> +/* @@trigger: delaydie */
> +
> +#pragma D option quiet
> +#pragma D option strsize=12
> +
> +syscall::write:entry
> +/pid == $target/
> +{
> +	printf("%s char match\n", (s = copyinstr(arg1, 96))[4] == 'y' ? "good" : "BAD");
> +	printf("'%s'", s);
> +	exit(0);
> +}
> +
> +ERROR
> +{
> +	exit(1);
> +}
> diff --git a/test/unittest/funcs/copyinstr/tst.copyinstr-high-maxsize.r b/test/unittest/funcs/copyinstr/tst.copyinstr-high-maxsize.r
> new file mode 100644
> index 00000000..e6d97c74
> --- /dev/null
> +++ b/test/unittest/funcs/copyinstr/tst.copyinstr-high-maxsize.r
> @@ -0,0 +1,4 @@
> +good char match
> +'Delay in ns'
> +-- @@stderr --
> +Delay in ns needed in delay env var.



More information about the DTrace-devel mailing list