Message ID | 20220513155749.2488070-4-afaria@redhat.com |
---|---|
State | New |
Headers | show |
Series | Implement bdrv_{pread, pwrite, pwrite_sync, pwrite_zeroes}() using generated_co_wrapper | expand |
On Fri, May 13, 2022 at 04:57:45PM +0100, Alberto Faria wrote: > For consistency with other I/O functions, and in preparation to > implement bdrv_{pread,pwrite}() using generated_co_wrapper. > > unsigned int fits in int64_t, so all callers remain correct. However, future callers that pass in something larger than unsigned int... > +++ b/include/block/block_int-io.h > @@ -56,7 +56,7 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, > QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags); > > static inline int coroutine_fn bdrv_co_pread(BdrvChild *child, > - int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags) > + int64_t offset, int64_t bytes, void *buf, BdrvRequestFlags flags) > { > QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); ...now end up calling QEMU_IOVEC_INIT_BUF() which tries to do .local_iov.iov_len = bytes, which can silently overflow on 32-bit platforms where iov_len is size_t. We need to add a code guard that callers do not pass in too large of a buffer. > IO_CODE(); > @@ -65,7 +65,7 @@ static inline int coroutine_fn bdrv_co_pread(BdrvChild *child, > } > > static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child, > - int64_t offset, unsigned int bytes, const void *buf, BdrvRequestFlags flags) > + int64_t offset, int64_t bytes, const void *buf, BdrvRequestFlags flags) > { > QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); Here as well.
On Tue, May 17, 2022 at 3:33 PM Eric Blake <eblake@redhat.com> wrote: > ...now end up calling QEMU_IOVEC_INIT_BUF() which tries to do > .local_iov.iov_len = bytes, which can silently overflow on 32-bit > platforms where iov_len is size_t. We need to add a code guard that > callers do not pass in too large of a buffer. I see. blk_co_pread() and blk_co_pwrite() use assert(bytes <= SIZE_MAX). Would that be an appropriate safeguard here? Or should we return an error? Alberto
On Tue, May 17, 2022 at 03:48:59PM +0100, Alberto Faria wrote: > On Tue, May 17, 2022 at 3:33 PM Eric Blake <eblake@redhat.com> wrote: > > ...now end up calling QEMU_IOVEC_INIT_BUF() which tries to do > > .local_iov.iov_len = bytes, which can silently overflow on 32-bit > > platforms where iov_len is size_t. We need to add a code guard that > > callers do not pass in too large of a buffer. > > I see. blk_co_pread() and blk_co_pwrite() use assert(bytes <= > SIZE_MAX). Would that be an appropriate safeguard here? Or should we > return an error? I'd be okay with the assert.
diff --git a/block/coroutines.h b/block/coroutines.h index 830ecaa733..3f41238b33 100644 --- a/block/coroutines.h +++ b/block/coroutines.h @@ -91,11 +91,11 @@ int coroutine_fn blk_co_do_flush(BlockBackend *blk); */ int generated_co_wrapper -bdrv_preadv(BdrvChild *child, int64_t offset, unsigned int bytes, +bdrv_preadv(BdrvChild *child, int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); int generated_co_wrapper -bdrv_pwritev(BdrvChild *child, int64_t offset, unsigned int bytes, +bdrv_pwritev(BdrvChild *child, int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); int generated_co_wrapper diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h index d4d3bed783..d1a6970dc6 100644 --- a/include/block/block_int-io.h +++ b/include/block/block_int-io.h @@ -56,7 +56,7 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags); static inline int coroutine_fn bdrv_co_pread(BdrvChild *child, - int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags) + int64_t offset, int64_t bytes, void *buf, BdrvRequestFlags flags) { QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); IO_CODE(); @@ -65,7 +65,7 @@ static inline int coroutine_fn bdrv_co_pread(BdrvChild *child, } static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child, - int64_t offset, unsigned int bytes, const void *buf, BdrvRequestFlags flags) + int64_t offset, int64_t bytes, const void *buf, BdrvRequestFlags flags) { QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); IO_CODE();