[DTrace-devel] [PATCH] print: Fix truncation

Kris Van Hees kvanhees at kvh-deb-bpf.us.oracle.com
Tue Jan 30 16:06:47 UTC 2024


On Fri, Dec 22, 2023 at 07:51:15PM -0500, eugene.loh at oracle.com wrote:
> 
> The printsize option can be used to limit how much data is reported
> by print().  A few corrections are needed.
> 
> 1)  In dt_print_visit(), we check if offset/NBBY > dv_size.  E.g.,
> if a 40-byte limit is set, then an 8-byte record at offset 40 will
> be reported.  Change to offset/NBBY >= dv_size.  We do not worry
> about the case where the print size ends in the middle of a record.
> 
> 2)  dt_print_type() sets the size and then calls dt_print_visit().
> But dt_print_visit() can also call itself recursively, and in this
> case dv_size is not set.  The dv_size values at deeper depths are
> garbage.  Have dt_print_visit() set dva2.dt_size.
> 
> The existing test for -xprintsize is corrected and a new test,
> focused on truncation at deeper depths, is added.
> 
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>

Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>

> ---
>  libdtrace/dt_printf.c                        |   3 +-
>  test/unittest/print/tst.print.local.trunc.d  |   9 +-
>  test/unittest/print/tst.print.local.trunc.r  |   1 +
>  test/unittest/print/tst.print.local.trunc2.d |  55 ++++++++
>  test/unittest/print/tst.print.local.trunc2.r | 125 +++++++++++++++++++
>  5 files changed, 191 insertions(+), 2 deletions(-)
>  create mode 100644 test/unittest/print/tst.print.local.trunc2.d
>  create mode 100644 test/unittest/print/tst.print.local.trunc2.r
> 
> diff --git a/libdtrace/dt_printf.c b/libdtrace/dt_printf.c
> index 2658c6a8..e844dc1b 100644
> --- a/libdtrace/dt_printf.c
> +++ b/libdtrace/dt_printf.c
> @@ -1993,7 +1993,7 @@ dt_print_visit(const char *name, ctf_id_t type, unsigned long offset,
>  	int i;
>  
>  	/* run out of data to display, or hit depth limit? */
> -	if ((offset/NBBY) > dva->dv_size || depth >= DT_PRINT_DEPTH) {
> +	if ((offset/NBBY) >= dva->dv_size || depth >= DT_PRINT_DEPTH) {
>  		dt_printf(dva->dv_dtp, dva->dv_fp, "%*s...\n",
>  			  dva->dv_startindent + depth, "");
>  		return -1;
> @@ -2197,6 +2197,7 @@ doprint:
>  		dva2.dv_fp = dva->dv_fp;
>  		dva2.dv_data = dva->dv_data;
>  		dva2.dv_startindent = dva->dv_startindent;
> +		dva2.dv_size = dva->dv_size;
>  		if (ctf_type_encoding(dva->dv_ctfp, a.ctr_contents, &e) < 0) {
>  			dt_dprintf("error retrieving type encoding for array contents in [%ld]: %s\n",
>  				   a.ctr_contents,
> diff --git a/test/unittest/print/tst.print.local.trunc.d b/test/unittest/print/tst.print.local.trunc.d
> index 25ad54b0..2e40dd84 100644
> --- a/test/unittest/print/tst.print.local.trunc.d
> +++ b/test/unittest/print/tst.print.local.trunc.d
> @@ -41,9 +41,16 @@ BEGIN
>  	t->s.f = 100,
>  	t->g = 1;
>  	t->h = FIRSTVAL;
> +	printf("a %d; b %d; u %d; s %d; g %d; h %d\n",
> +	    offsetof(struct test_struct, a),
> +	    offsetof(struct test_struct, b),
> +	    offsetof(struct test_struct, u),
> +	    offsetof(struct test_struct, s),
> +	    offsetof(struct test_struct, g),
> +	    offsetof(struct test_struct, h));
>  	print(t);
>  	/* ensure printsize can be dynamically changed */
> -	setopt("printsize", "16");
> +	setopt("printsize", "24");
>  	print(t);
>  	exit(0);
>  }
> diff --git a/test/unittest/print/tst.print.local.trunc.r b/test/unittest/print/tst.print.local.trunc.r
> index df5708d9..8cefaa17 100644
> --- a/test/unittest/print/tst.print.local.trunc.r
> +++ b/test/unittest/print/tst.print.local.trunc.r
> @@ -1,3 +1,4 @@
> +a 0; b 4; u 16; s 24; g 40; h 44
>  {ptr} = *
>                                              (struct test_struct) {
>                                               .a = (int)1,
> diff --git a/test/unittest/print/tst.print.local.trunc2.d b/test/unittest/print/tst.print.local.trunc2.d
> new file mode 100644
> index 00000000..5f500fc8
> --- /dev/null
> +++ b/test/unittest/print/tst.print.local.trunc2.d
> @@ -0,0 +1,55 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 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.
> + */
> +/* @@nosort */
> +
> +#pragma D option quiet
> +
> +struct test_struct {
> +	long long	x;
> +	struct {
> +		long long x;
> +		struct {
> +			long long x;
> +			struct {
> +				long long x;
> +				struct {
> +					long long x;
> +					struct {
> +						long long x;
> +						struct {
> +							long long x;
> +							struct {
> +								long long x;
> +							} g;
> +						} f;
> +					} e;
> +				} d;
> +			} c;
> +		} b;
> +	} a;
> +};
> +
> +BEGIN
> +{
> +	t = (struct test_struct *)alloca(sizeof (struct test_struct));
> +	t->x = 1111111111111111ll;
> +	t->a.x = 2222222222222222ll;
> +	t->a.b.x = 3333333333333333ll;
> +	t->a.b.c.x = 4444444444444444ll;
> +	t->a.b.c.d.x = 5555555555555555ll;
> +	t->a.b.c.d.e.x = 6666666666666666ll;
> +	t->a.b.c.d.e.f.x = 7777777777777777ll;
> +	t->a.b.c.d.e.f.g.x = 8888888888888888ll;
> +
> +	setopt("printsize", "90"); print(t);
> +	setopt("printsize", "64"); print(t);
> +	setopt("printsize", "56"); print(t);
> +	setopt("printsize", "48"); print(t);
> +	setopt("printsize", "40"); print(t);
> +	setopt("printsize", "32"); print(t);
> +	exit(0);
> +}
> diff --git a/test/unittest/print/tst.print.local.trunc2.r b/test/unittest/print/tst.print.local.trunc2.r
> new file mode 100644
> index 00000000..7de3136c
> --- /dev/null
> +++ b/test/unittest/print/tst.print.local.trunc2.r
> @@ -0,0 +1,125 @@
> +{ptr} = *
> +                                            (struct test_struct) {
> +                                             .x = (long long)1111111111111111,
> +                                             .a = (struct) {
> +                                              .x = (long long)2222222222222222,
> +                                              .b = (struct) {
> +                                               .x = (long long)3333333333333333,
> +                                               .c = (struct) {
> +                                                .x = (long long)4444444444444444,
> +                                                .d = (struct) {
> +                                                 .x = (long long)5555555555555555,
> +                                                 .e = (struct) {
> +                                                  .x = (long long)6666666666666666,
> +                                                  .f = (struct) {
> +                                                   .x = (long long)7777777777777777,
> +                                                   .g = (struct) {
> +                                                    .x = (long long)8888888888888888,
> +                                                   },
> +                                                  },
> +                                                 },
> +                                                },
> +                                               },
> +                                              },
> +                                             },
> +                                            }
> +{ptr} = *
> +                                            (struct test_struct) {
> +                                             .x = (long long)1111111111111111,
> +                                             .a = (struct) {
> +                                              .x = (long long)2222222222222222,
> +                                              .b = (struct) {
> +                                               .x = (long long)3333333333333333,
> +                                               .c = (struct) {
> +                                                .x = (long long)4444444444444444,
> +                                                .d = (struct) {
> +                                                 .x = (long long)5555555555555555,
> +                                                 .e = (struct) {
> +                                                  .x = (long long)6666666666666666,
> +                                                  .f = (struct) {
> +                                                   .x = (long long)7777777777777777,
> +                                                   .g = (struct) {
> +                                                    .x = (long long)8888888888888888,
> +                                                   },
> +                                                  },
> +                                                 },
> +                                                },
> +                                               },
> +                                              },
> +                                             },
> +                                            }
> +{ptr} = *
> +                                            (struct test_struct) {
> +                                             .x = (long long)1111111111111111,
> +                                             .a = (struct) {
> +                                              .x = (long long)2222222222222222,
> +                                              .b = (struct) {
> +                                               .x = (long long)3333333333333333,
> +                                               .c = (struct) {
> +                                                .x = (long long)4444444444444444,
> +                                                .d = (struct) {
> +                                                 .x = (long long)5555555555555555,
> +                                                 .e = (struct) {
> +                                                  .x = (long long)6666666666666666,
> +                                                  .f = (struct) {
> +                                                   .x = (long long)7777777777777777,
> +                                                   ...
> +                                                  },
> +                                                 },
> +                                                },
> +                                               },
> +                                              },
> +                                             },
> +                                            }
> +{ptr} = *
> +                                            (struct test_struct) {
> +                                             .x = (long long)1111111111111111,
> +                                             .a = (struct) {
> +                                              .x = (long long)2222222222222222,
> +                                              .b = (struct) {
> +                                               .x = (long long)3333333333333333,
> +                                               .c = (struct) {
> +                                                .x = (long long)4444444444444444,
> +                                                .d = (struct) {
> +                                                 .x = (long long)5555555555555555,
> +                                                 .e = (struct) {
> +                                                  .x = (long long)6666666666666666,
> +                                                  ...
> +                                                 },
> +                                                },
> +                                               },
> +                                              },
> +                                             },
> +                                            }
> +{ptr} = *
> +                                            (struct test_struct) {
> +                                             .x = (long long)1111111111111111,
> +                                             .a = (struct) {
> +                                              .x = (long long)2222222222222222,
> +                                              .b = (struct) {
> +                                               .x = (long long)3333333333333333,
> +                                               .c = (struct) {
> +                                                .x = (long long)4444444444444444,
> +                                                .d = (struct) {
> +                                                 .x = (long long)5555555555555555,
> +                                                 ...
> +                                                },
> +                                               },
> +                                              },
> +                                             },
> +                                            }
> +{ptr} = *
> +                                            (struct test_struct) {
> +                                             .x = (long long)1111111111111111,
> +                                             .a = (struct) {
> +                                              .x = (long long)2222222222222222,
> +                                              .b = (struct) {
> +                                               .x = (long long)3333333333333333,
> +                                               .c = (struct) {
> +                                                .x = (long long)4444444444444444,
> +                                                ...
> +                                               },
> +                                              },
> +                                             },
> +                                            }
> +
> -- 
> 2.18.4
> 
> 



More information about the DTrace-devel mailing list