[DTrace-devel] [PATCH v2] Ensure string constants that are too long are truncated correctly

Eugene Loh eugene.loh at oracle.com
Mon Nov 22 18:58:29 UTC 2021


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

This patch seems to orphan dt_strtab.  Specifically (not that this is a 
big deal), the zalloc() no longer has a partner free in dtrace_close() 
(or dt_difo_free... which I do not understand).

The two-byte encoding of the string-length prefix is hard-wired in lots 
of places but oh well.  Not a great practice, but so be it.

On 11/20/21 12:28 AM, Kris Van Hees via DTrace-devel wrote:
> The string table can contain strings that are longer than the maximum
> string size for the program being compiled.  They need to be truncated
> before they are used to ensure that string operations work correctly.
>
> Since string constants can be used verbatim or as values of built-in
> variables, it is easiest to just pre-process the string table before it
> is loaded into the 'strtab' BPF map.  Every string that is longer than
> the maximum string size has its length prefix set to the maximum string
> size and the string itself is truncated to that length.
>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>   libdtrace/dt_bpf.c                           | 27 ++++++++++++++++----
>   test/unittest/codegen/tst.str_const_length.d | 21 +++++++++++++++
>   test/unittest/codegen/tst.str_const_length.r |  4 +++
>   3 files changed, 47 insertions(+), 5 deletions(-)
>   create mode 100644 test/unittest/codegen/tst.str_const_length.d
>   create mode 100644 test/unittest/codegen/tst.str_const_length.r
>
> diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
> index e0134a93..fc1e5e8f 100644
> --- a/libdtrace/dt_bpf.c
> +++ b/libdtrace/dt_bpf.c
> @@ -240,6 +240,9 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
>   	int		stabsz, gvarsz, lvarsz, tvarc, aggsz, memsz;
>   	int		ci_mapfd, st_mapfd, pr_mapfd;
>   	uint32_t	key = 0;
> +	size_t		strsize = dtp->dt_options[DTRACEOPT_STRSIZE];
> +	uint8_t		*buf, *end;
> +	char		*strtab;
>   
>   	/* If we already created the global maps, return success. */
>   	if (dt_gmap_done)
> @@ -325,13 +328,27 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
>   	 * value that is used to store the strtab.
>   	 */
>   	dtp->dt_strlen = dt_strtab_size(dtp->dt_ccstab);
> -	stabsz = dtp->dt_strlen + dtp->dt_options[DTRACEOPT_STRSIZE];
> -	dtp->dt_strtab = dt_zalloc(dtp, stabsz);
> -	if (dtp->dt_strtab == NULL)
> +	stabsz = dtp->dt_strlen + strsize;
> +	strtab = dt_zalloc(dtp, stabsz);
> +	if (strtab == NULL)
>   		return dt_set_errno(dtp, EDT_NOMEM);
>   
>   	dt_strtab_write(dtp->dt_ccstab, (dt_strtab_write_f *)dt_strtab_copystr,
> -			dtp->dt_strtab);
> +			strtab);
> +
> +	/* Loop over the string table and truncate strings that are too long. */
> +	buf = (uint8_t *)strtab;
> +	end = buf + dtp->dt_strlen;
> +	while (buf < end) {
> +		uint_t	len = (buf[0] << 8) | buf[1];
> +
> +		if (len > strsize) {
> +			buf[0] = strsize >> 8;
> +			buf[1] = strsize & 0xff;
> +			buf[2 + strsize] = '\0';
> +		}
> +		buf += 2 + len + 1;
> +	}
>   
>   	st_mapfd = create_gmap(dtp, "strtab", BPF_MAP_TYPE_ARRAY,
>   			       sizeof(uint32_t), stabsz, 1);
> @@ -363,7 +380,7 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
>   	dt_bpf_map_update(ci_mapfd, &key, dtp->dt_conf.cpus);
>   
>   	/* Populate the 'strtab' map. */
> -	dt_bpf_map_update(st_mapfd, &key, dtp->dt_strtab);
> +	dt_bpf_map_update(st_mapfd, &key, strtab);
>   
>   	/* Populate the 'probes' map. */
>   	populate_probes_map(dtp, pr_mapfd);
> diff --git a/test/unittest/codegen/tst.str_const_length.d b/test/unittest/codegen/tst.str_const_length.d
> new file mode 100644
> index 00000000..1c58ba13
> --- /dev/null
> +++ b/test/unittest/codegen/tst.str_const_length.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2021, 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.
> + */
> +
> +#pragma D option rawbytes
> +#pragma D option strsize=5
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	trace("abcdefgh");
> +	exit(0);
> +}
> +
> +ERROR
> +{
> +	exit(1);
> +}
> diff --git a/test/unittest/codegen/tst.str_const_length.r b/test/unittest/codegen/tst.str_const_length.r
> new file mode 100644
> index 00000000..b6991a71
> --- /dev/null
> +++ b/test/unittest/codegen/tst.str_const_length.r
> @@ -0,0 +1,4 @@
> +
> +             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
> +         0: 00 05 61 62 63 64 65 00                          ..abcde.
> +



More information about the DTrace-devel mailing list