Commit cf070d7ec0b8fb21faa9a630ed5cc66f90844a08
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); |