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 | 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); | ... | ... |