Commit cf070d7ec0b8fb21faa9a630ed5cc66f90844a08

Authored by Christoph Hellwig
Committed by Anthony Liguori
1 parent a7824a88

qemu-io: reject invalid pattern

Replace the use of atoi which is used for pattern parsing currently with
strtol.  Atoi won't parse sedecimal pattern values (it always returns 0),
but qemu-iotests use such pattern values.  Also reject every pattern
that is not a unsigned char as we pass the pattern to memset which
expect a bye value (despite having the pattern argument declared as int).

Based on an earlier patch by Stefan Weil which did not include the
error handling.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reported-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 1 changed file with 38 additions and 6 deletions
qemu-io.c
... ... @@ -26,6 +26,26 @@ static BlockDriverState *bs;
26 26 static int misalign;
27 27  
28 28 /*
  29 + * Parse the pattern argument to various sub-commands.
  30 + *
  31 + * Because the pattern is used as an argument to memset it must evaluate
  32 + * to an unsigned integer that fits into a single byte.
  33 + */
  34 +static int parse_pattern(const char *arg)
  35 +{
  36 + char *endptr = NULL;
  37 + long pattern;
  38 +
  39 + pattern = strtol(arg, &endptr, 0);
  40 + if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
  41 + printf("%s is not a valid pattern byte\n", arg);
  42 + return -1;
  43 + }
  44 +
  45 + return pattern;
  46 +}
  47 +
  48 +/*
29 49 * Memory allocation helpers.
30 50 *
31 51 * Make sure memory is aligned by default, or purposefully misaligned if
... ... @@ -304,7 +324,9 @@ read_f(int argc, char **argv)
304 324 break;
305 325 case 'P':
306 326 Pflag = 1;
307   - pattern = atoi(optarg);
  327 + pattern = parse_pattern(optarg);
  328 + if (pattern < 0)
  329 + return 0;
308 330 break;
309 331 case 'q':
310 332 qflag = 1;
... ... @@ -469,7 +491,9 @@ readv_f(int argc, char **argv)
469 491 break;
470 492 case 'P':
471 493 Pflag = 1;
472   - pattern = atoi(optarg);
  494 + pattern = parse_pattern(optarg);
  495 + if (pattern < 0)
  496 + return 0;
473 497 break;
474 498 case 'q':
475 499 qflag = 1;
... ... @@ -594,7 +618,9 @@ write_f(int argc, char **argv)
594 618 pflag = 1;
595 619 break;
596 620 case 'P':
597   - pattern = atoi(optarg);
  621 + pattern = parse_pattern(optarg);
  622 + if (pattern < 0)
  623 + return 0;
598 624 break;
599 625 case 'q':
600 626 qflag = 1;
... ... @@ -721,7 +747,9 @@ writev_f(int argc, char **argv)
721 747 qflag = 1;
722 748 break;
723 749 case 'P':
724   - pattern = atoi(optarg);
  750 + pattern = parse_pattern(optarg);
  751 + if (pattern < 0)
  752 + return 0;
725 753 break;
726 754 default:
727 755 return command_usage(&writev_cmd);
... ... @@ -895,7 +923,9 @@ aio_read_f(int argc, char **argv)
895 923 break;
896 924 case 'P':
897 925 ctx->Pflag = 1;
898   - ctx->pattern = atoi(optarg);
  926 + ctx->pattern = parse_pattern(optarg);
  927 + if (ctx->pattern < 0)
  928 + return 0;
899 929 break;
900 930 case 'q':
901 931 ctx->qflag = 1;
... ... @@ -995,7 +1025,9 @@ aio_write_f(int argc, char **argv)
995 1025 ctx->qflag = 1;
996 1026 break;
997 1027 case 'P':
998   - pattern = atoi(optarg);
  1028 + pattern = parse_pattern(optarg);
  1029 + if (pattern < 0)
  1030 + return 0;
999 1031 break;
1000 1032 default:
1001 1033 free(ctx);
... ...