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