From 3785a4d83bd51b650c2dd09e800d5d39f570951e Mon Sep 17 00:00:00 2001 From: wuzhouhui Date: Tue, 9 Oct 2018 13:10:33 +0800 Subject: [PATCH] bdev/qos: fix a heap-use-after-free error When destroy qos, spdk_bdev_qos_destroy() allocates a new qos, and swap old one. After spdk_bdev_unregister() frees the new qos, the old qos poller may still reference new qos via bdev->internal.qos. Fix this error by using old qos in _spdk_bdev_qos_io_submit(). Reported in https://ci.spdk.io/spdk/builds/review/72aac514303059322578524137b31bf47b104f67.1539054028/ubuntu16.04/build.log Change-Id: Id1bce6c8b1cefae604dd2c69e8f3482ec34b1b54 Signed-off-by: wuzhouhui Reviewed-on: https://review.gerrithub.io/428444 Chandler-Test-Pool: SPDK Automated Test System Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/bdev/bdev.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 3a4fef817..09df169be 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -1130,11 +1130,10 @@ _spdk_bdev_qos_update_per_io(struct spdk_bdev_qos *qos, uint64_t io_size_in_byte } static void -_spdk_bdev_qos_io_submit(struct spdk_bdev_channel *ch) +_spdk_bdev_qos_io_submit(struct spdk_bdev_channel *ch, struct spdk_bdev_qos *qos) { struct spdk_bdev_io *bdev_io = NULL; struct spdk_bdev *bdev = ch->bdev; - struct spdk_bdev_qos *qos = bdev->internal.qos; struct spdk_bdev_shared_resource *shared_resource = ch->shared_resource; int i; bool to_limit_io; @@ -1381,7 +1380,7 @@ _spdk_bdev_io_submit(void *ctx) bdev_ch->io_outstanding--; shared_resource->io_outstanding--; TAILQ_INSERT_TAIL(&bdev->internal.qos->queued, bdev_io, internal.link); - _spdk_bdev_qos_io_submit(bdev_ch); + _spdk_bdev_qos_io_submit(bdev_ch, bdev->internal.qos); } else { SPDK_ERRLOG("unknown bdev_ch flag %x found\n", bdev_ch->flags); spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); @@ -1544,7 +1543,7 @@ spdk_bdev_channel_poll_qos(void *arg) } } - _spdk_bdev_qos_io_submit(qos->ch); + _spdk_bdev_qos_io_submit(qos->ch, qos); return -1; }