diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2024-05-07 14:05:58 -0400 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2024-06-10 11:05:43 +0200 |
commit | 365911b182017f05122b88a574477ff945ae91ab (patch) | |
tree | aa4948068a6b2f3d72ea4a8ccf6f45221d8d5b0b | |
parent | e669e800fc9ef8806af5c5578249ab758a4f8a5a (diff) | |
download | qemu-365911b182017f05122b88a574477ff945ae91ab.zip qemu-365911b182017f05122b88a574477ff945ae91ab.tar.gz qemu-365911b182017f05122b88a574477ff945ae91ab.tar.bz2 |
qemu-io: add cvtnum() error handling for zone commands
cvtnum() parses positive int64_t values and returns a negative errno on
failure. Print errors and return early when cvtnum() fails.
While we're at it, also reject nr_zones values greater or equal to 2^32
since they cannot be represented.
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Cc: Sam Li <faithilikerun@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240507180558.377233-1-stefanha@redhat.com>
Reviewed-by: Sam Li <faithilikerun@gmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | qemu-io-cmds.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index f5d7202..e2fab57 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1739,12 +1739,26 @@ static int zone_report_f(BlockBackend *blk, int argc, char **argv) { int ret; int64_t offset; + int64_t val; unsigned int nr_zones; ++optind; offset = cvtnum(argv[optind]); + if (offset < 0) { + print_cvtnum_err(offset, argv[optind]); + return offset; + } ++optind; - nr_zones = cvtnum(argv[optind]); + val = cvtnum(argv[optind]); + if (val < 0) { + print_cvtnum_err(val, argv[optind]); + return val; + } + if (val > UINT_MAX) { + printf("Number of zones must be less than 2^32\n"); + return -ERANGE; + } + nr_zones = val; g_autofree BlockZoneDescriptor *zones = NULL; zones = g_new(BlockZoneDescriptor, nr_zones); @@ -1780,8 +1794,16 @@ static int zone_open_f(BlockBackend *blk, int argc, char **argv) int64_t offset, len; ++optind; offset = cvtnum(argv[optind]); + if (offset < 0) { + print_cvtnum_err(offset, argv[optind]); + return offset; + } ++optind; len = cvtnum(argv[optind]); + if (len < 0) { + print_cvtnum_err(len, argv[optind]); + return len; + } ret = blk_zone_mgmt(blk, BLK_ZO_OPEN, offset, len); if (ret < 0) { printf("zone open failed: %s\n", strerror(-ret)); @@ -1805,8 +1827,16 @@ static int zone_close_f(BlockBackend *blk, int argc, char **argv) int64_t offset, len; ++optind; offset = cvtnum(argv[optind]); + if (offset < 0) { + print_cvtnum_err(offset, argv[optind]); + return offset; + } ++optind; len = cvtnum(argv[optind]); + if (len < 0) { + print_cvtnum_err(len, argv[optind]); + return len; + } ret = blk_zone_mgmt(blk, BLK_ZO_CLOSE, offset, len); if (ret < 0) { printf("zone close failed: %s\n", strerror(-ret)); @@ -1830,8 +1860,16 @@ static int zone_finish_f(BlockBackend *blk, int argc, char **argv) int64_t offset, len; ++optind; offset = cvtnum(argv[optind]); + if (offset < 0) { + print_cvtnum_err(offset, argv[optind]); + return offset; + } ++optind; len = cvtnum(argv[optind]); + if (len < 0) { + print_cvtnum_err(len, argv[optind]); + return len; + } ret = blk_zone_mgmt(blk, BLK_ZO_FINISH, offset, len); if (ret < 0) { printf("zone finish failed: %s\n", strerror(-ret)); @@ -1855,8 +1893,16 @@ static int zone_reset_f(BlockBackend *blk, int argc, char **argv) int64_t offset, len; ++optind; offset = cvtnum(argv[optind]); + if (offset < 0) { + print_cvtnum_err(offset, argv[optind]); + return offset; + } ++optind; len = cvtnum(argv[optind]); + if (len < 0) { + print_cvtnum_err(len, argv[optind]); + return len; + } ret = blk_zone_mgmt(blk, BLK_ZO_RESET, offset, len); if (ret < 0) { printf("zone reset failed: %s\n", strerror(-ret)); |