[PATCH v1] strace: Enhance --string-limit/-s to remove max string length limit
Dmitry V. Levin
ldv at strace.io
Thu Jan 25 11:16:12 UTC 2024
On Sun, Jan 21, 2024 at 04:16:02PM +0530, Gautam Menghani wrote:
> Enhance the -s STRSIZE/--string-limit=STRSIZE option to provide the
> ability to remove the max string length limit with the value argument
> 'inf'. This patch resolves issue 269 on github.
Another issue I see just by looking at the patch is potential integer
overflow followed by memory corruption:
> @@ -2562,10 +2564,15 @@ init(int argc, char *argv[])
> error_opt_arg(c, lopt, optarg);
> break;
> case 's':
> - i = string_to_uint(optarg);
> - if (i < 0 || (unsigned int) i > -1U / 4)
> + if (isdigit(*optarg)) {
> + i = string_to_uint(optarg);
> + if (i < 0 || (unsigned int) i > -1U / 4)
> + error_opt_arg(c, lopt, optarg);
> + max_strlen = i;
> + } else if (strcmp(optarg, "inf") == 0)
> + truncate_output = false;
> + else
> error_opt_arg(c, lopt, optarg);
> - max_strlen = i;
> break;
> case 'S':
> set_sortby(optarg);
Note that before this change max_strlen was always less than -1U / 4.
> diff --git a/src/util.c b/src/util.c
> index 92c0577ce..68fb0277e 100644
> --- a/src/util.c
> +++ b/src/util.c
> @@ -22,6 +22,7 @@
> # include <sys/xattr.h>
> #endif
> #include <sys/uio.h>
> +#include <sys/sysinfo.h>
>
> #include "largefile_wrappers.h"
> #include "number_set.h"
> @@ -1258,30 +1259,39 @@ printstr_ex(struct tcb *const tcp, const kernel_ulong_t addr,
> static char *str;
> static char *outstr;
>
> - unsigned int size;
> + unsigned long size;
> unsigned int style = user_style;
> + unsigned long max_len = max_strlen;
> int rc;
> int ellipsis;
> + struct sysinfo info;
>
> if (!addr) {
> tprint_null();
> return -1;
> }
> +
> + if (!truncate_output) {
> + sysinfo(&info);
Note that expensive sysinfo() is now being called on every printstr_ex()
invocation.
> + max_len = info.totalram;
> + }
> +
> /* Allocate static buffers if they are not allocated yet. */
> +
> if (!str) {
> const unsigned int outstr_size =
> - 4 * max_strlen + /* for quotes and NUL */ 3;
> + 4 * max_len + /* for quotes and NUL */ 3;
Unlike former max_strlen, the max_len obtained from info.totalram can
easily exceed -1U / 4, resulting to outstr_size overflow.
> /*
> * We can assume that outstr_size / 4 == max_strlen
> * since we have a guarantee that max_strlen <= -1U / 4.
> */
>
> - str = xmalloc(max_strlen + 1);
> + str = xmalloc(max_len + 1);
> outstr = xmalloc(outstr_size);
If outstr_size ends up with a value that is less than 4 * max_len + 3,
then outstr would point to a small buffer, resulting to subsequent memory
corruption.
By the way, allocating 4 * totalram of memory is a very questionable idea.
--
ldv
More information about the Strace-devel
mailing list