if the blocksize of an iSCSI LUN is bigger than the BDRV_SECTOR_SIZE it is possible that sector_num or nb_sectors are not correctly alligned.
to avoid corruption we fail requests which are misaligned. Signed-off-by: Peter Lieven <p...@kamp.de> --- block/iscsi.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/block/iscsi.c b/block/iscsi.c index 0567b46..bff2e1f 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -298,6 +298,13 @@ static int64_t sector_lun2qemu(int64_t sector, IscsiLun *iscsilun) return sector * iscsilun->block_size / BDRV_SECTOR_SIZE; } +static int64_t is_request_lun_aligned(int64_t sector_num, int nb_sectors, + IscsiLun *iscsilun) +{ + return ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size || + (nb_sectors * BDRV_SECTOR_SIZE) % iscsilun->block_size) ? 0 : 1; +} + static int iscsi_aio_writev_acb(IscsiAIOCB *acb) { @@ -382,6 +389,10 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num, IscsiLun *iscsilun = bs->opaque; IscsiAIOCB *acb; + if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + return NULL; + } + acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque); trace_iscsi_aio_writev(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb); @@ -524,6 +535,10 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num, IscsiLun *iscsilun = bs->opaque; IscsiAIOCB *acb; + if (!is_request_lun_aligned(sector_num, 0, iscsilun)) { + return NULL; + } + acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque); trace_iscsi_aio_readv(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb); @@ -687,6 +702,10 @@ iscsi_aio_discard(BlockDriverState *bs, IscsiLun *iscsilun = bs->opaque; IscsiAIOCB *acb; + if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + return NULL; + } + acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque); acb->iscsilun = iscsilun; @@ -878,6 +897,10 @@ static int coroutine_fn iscsi_co_is_allocated(BlockDriverState *bs, struct IscsiTask iTask; int ret; + if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + goto fail; + } + /* LUN does not support logical block provisioning */ if (iscsilun->lbpme == 0) { *pnum = nb_sectors; @@ -949,6 +972,10 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, struct IscsiTask iTask; struct unmap_list list[1]; + if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + return -EIO; + } + if (!iscsilun->lbprz || !iscsilun->lbpu || !(bs->open_flags & BDRV_O_UNMAP) || sector_qemu2lun(nb_sectors, iscsilun) > iscsilun->max_unmap) { /* fall back to writev */ -- 1.7.9.5