Commit 3785a4d8 authored by wuzhouhui's avatar wuzhouhui Committed by Jim Harris
Browse files

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: default avatarwuzhouhui <wuzhouhui@kingsoft.com>
Reviewed-on: https://review.gerrithub.io/428444


Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 346fefc3
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -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;
}