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,6 +26,26 @@ static BlockDriverState *bs;
26 static int misalign; 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 * Memory allocation helpers. 49 * Memory allocation helpers.
30 * 50 *
31 * Make sure memory is aligned by default, or purposefully misaligned if 51 * Make sure memory is aligned by default, or purposefully misaligned if
@@ -304,7 +324,9 @@ read_f(int argc, char **argv) @@ -304,7 +324,9 @@ read_f(int argc, char **argv)
304 break; 324 break;
305 case 'P': 325 case 'P':
306 Pflag = 1; 326 Pflag = 1;
307 - pattern = atoi(optarg); 327 + pattern = parse_pattern(optarg);
  328 + if (pattern < 0)
  329 + return 0;
308 break; 330 break;
309 case 'q': 331 case 'q':
310 qflag = 1; 332 qflag = 1;
@@ -469,7 +491,9 @@ readv_f(int argc, char **argv) @@ -469,7 +491,9 @@ readv_f(int argc, char **argv)
469 break; 491 break;
470 case 'P': 492 case 'P':
471 Pflag = 1; 493 Pflag = 1;
472 - pattern = atoi(optarg); 494 + pattern = parse_pattern(optarg);
  495 + if (pattern < 0)
  496 + return 0;
473 break; 497 break;
474 case 'q': 498 case 'q':
475 qflag = 1; 499 qflag = 1;
@@ -594,7 +618,9 @@ write_f(int argc, char **argv) @@ -594,7 +618,9 @@ write_f(int argc, char **argv)
594 pflag = 1; 618 pflag = 1;
595 break; 619 break;
596 case 'P': 620 case 'P':
597 - pattern = atoi(optarg); 621 + pattern = parse_pattern(optarg);
  622 + if (pattern < 0)
  623 + return 0;
598 break; 624 break;
599 case 'q': 625 case 'q':
600 qflag = 1; 626 qflag = 1;
@@ -721,7 +747,9 @@ writev_f(int argc, char **argv) @@ -721,7 +747,9 @@ writev_f(int argc, char **argv)
721 qflag = 1; 747 qflag = 1;
722 break; 748 break;
723 case 'P': 749 case 'P':
724 - pattern = atoi(optarg); 750 + pattern = parse_pattern(optarg);
  751 + if (pattern < 0)
  752 + return 0;
725 break; 753 break;
726 default: 754 default:
727 return command_usage(&writev_cmd); 755 return command_usage(&writev_cmd);
@@ -895,7 +923,9 @@ aio_read_f(int argc, char **argv) @@ -895,7 +923,9 @@ aio_read_f(int argc, char **argv)
895 break; 923 break;
896 case 'P': 924 case 'P':
897 ctx->Pflag = 1; 925 ctx->Pflag = 1;
898 - ctx->pattern = atoi(optarg); 926 + ctx->pattern = parse_pattern(optarg);
  927 + if (ctx->pattern < 0)
  928 + return 0;
899 break; 929 break;
900 case 'q': 930 case 'q':
901 ctx->qflag = 1; 931 ctx->qflag = 1;
@@ -995,7 +1025,9 @@ aio_write_f(int argc, char **argv) @@ -995,7 +1025,9 @@ aio_write_f(int argc, char **argv)
995 ctx->qflag = 1; 1025 ctx->qflag = 1;
996 break; 1026 break;
997 case 'P': 1027 case 'P':
998 - pattern = atoi(optarg); 1028 + pattern = parse_pattern(optarg);
  1029 + if (pattern < 0)
  1030 + return 0;
999 break; 1031 break;
1000 default: 1032 default:
1001 free(ctx); 1033 free(ctx);