Skip to content

Commit 4f48120

Browse files
Ming Leiaxboe
authored andcommitted
blk-mq: prepare for implementing hctx table via xarray
It is inevitable to cause use-after-free on q->queue_hw_ctx between queue_for_each_hw_ctx() and blk_mq_update_nr_hw_queues(). And converting to xarray can fix the uaf, meantime code gets cleaner. Prepare for converting q->queue_hctx_ctx into xarray, one thing is that xa_for_each() can only accept 'unsigned long' as index, so changes type of hctx index of queue_for_each_hw_ctx() into 'unsigned long'. Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20220308073219.91173-6-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent de0328d commit 4f48120

File tree

6 files changed

+36
-29
lines changed

6 files changed

+36
-29
lines changed

block/blk-mq-debugfs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ static void debugfs_create_files(struct dentry *parent, void *data,
707707
void blk_mq_debugfs_register(struct request_queue *q)
708708
{
709709
struct blk_mq_hw_ctx *hctx;
710-
int i;
710+
unsigned long i;
711711

712712
debugfs_create_files(q->debugfs_dir, q, blk_mq_debugfs_queue_attrs);
713713

@@ -780,7 +780,7 @@ void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx)
780780
void blk_mq_debugfs_register_hctxs(struct request_queue *q)
781781
{
782782
struct blk_mq_hw_ctx *hctx;
783-
int i;
783+
unsigned long i;
784784

785785
queue_for_each_hw_ctx(q, hctx, i)
786786
blk_mq_debugfs_register_hctx(q, hctx);
@@ -789,7 +789,7 @@ void blk_mq_debugfs_register_hctxs(struct request_queue *q)
789789
void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)
790790
{
791791
struct blk_mq_hw_ctx *hctx;
792-
int i;
792+
unsigned long i;
793793

794794
queue_for_each_hw_ctx(q, hctx, i)
795795
blk_mq_debugfs_unregister_hctx(hctx);

block/blk-mq-sched.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ static void blk_mq_exit_sched_shared_tags(struct request_queue *queue)
515515
static void blk_mq_sched_tags_teardown(struct request_queue *q, unsigned int flags)
516516
{
517517
struct blk_mq_hw_ctx *hctx;
518-
int i;
518+
unsigned long i;
519519

520520
queue_for_each_hw_ctx(q, hctx, i) {
521521
if (hctx->sched_tags) {
@@ -550,9 +550,10 @@ static int blk_mq_init_sched_shared_tags(struct request_queue *queue)
550550

551551
int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)
552552
{
553-
unsigned int i, flags = q->tag_set->flags;
553+
unsigned int flags = q->tag_set->flags;
554554
struct blk_mq_hw_ctx *hctx;
555555
struct elevator_queue *eq;
556+
unsigned long i;
556557
int ret;
557558

558559
if (!e) {
@@ -618,7 +619,7 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)
618619
void blk_mq_sched_free_rqs(struct request_queue *q)
619620
{
620621
struct blk_mq_hw_ctx *hctx;
621-
int i;
622+
unsigned long i;
622623

623624
if (blk_mq_is_shared_tags(q->tag_set->flags)) {
624625
blk_mq_free_rqs(q->tag_set, q->sched_shared_tags,
@@ -635,7 +636,7 @@ void blk_mq_sched_free_rqs(struct request_queue *q)
635636
void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e)
636637
{
637638
struct blk_mq_hw_ctx *hctx;
638-
unsigned int i;
639+
unsigned long i;
639640
unsigned int flags = 0;
640641

641642
queue_for_each_hw_ctx(q, hctx, i) {

block/blk-mq-sysfs.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
206206
void blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
207207
{
208208
struct blk_mq_hw_ctx *hctx;
209-
int i;
209+
unsigned long i;
210210

211211
lockdep_assert_held(&q->sysfs_dir_lock);
212212

@@ -255,7 +255,8 @@ void blk_mq_sysfs_init(struct request_queue *q)
255255
int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
256256
{
257257
struct blk_mq_hw_ctx *hctx;
258-
int ret, i;
258+
unsigned long i, j;
259+
int ret;
259260

260261
WARN_ON_ONCE(!q->kobj.parent);
261262
lockdep_assert_held(&q->sysfs_dir_lock);
@@ -278,8 +279,10 @@ int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
278279
return ret;
279280

280281
unreg:
281-
while (--i >= 0)
282-
blk_mq_unregister_hctx(q->queue_hw_ctx[i]);
282+
queue_for_each_hw_ctx(q, hctx, j) {
283+
if (j < i)
284+
blk_mq_unregister_hctx(hctx);
285+
}
283286

284287
kobject_uevent(q->mq_kobj, KOBJ_REMOVE);
285288
kobject_del(q->mq_kobj);
@@ -290,7 +293,7 @@ int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
290293
void blk_mq_sysfs_unregister(struct request_queue *q)
291294
{
292295
struct blk_mq_hw_ctx *hctx;
293-
int i;
296+
unsigned long i;
294297

295298
mutex_lock(&q->sysfs_dir_lock);
296299
if (!q->mq_sysfs_init_done)
@@ -306,7 +309,8 @@ void blk_mq_sysfs_unregister(struct request_queue *q)
306309
int blk_mq_sysfs_register(struct request_queue *q)
307310
{
308311
struct blk_mq_hw_ctx *hctx;
309-
int i, ret = 0;
312+
unsigned long i;
313+
int ret = 0;
310314

311315
mutex_lock(&q->sysfs_dir_lock);
312316
if (!q->mq_sysfs_init_done)

block/blk-mq-tag.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_tag_iter_fn *fn,
515515
bt_for_each(NULL, q, btags, fn, priv, false);
516516
} else {
517517
struct blk_mq_hw_ctx *hctx;
518-
int i;
518+
unsigned long i;
519519

520520
queue_for_each_hw_ctx(q, hctx, i) {
521521
struct blk_mq_tags *tags = hctx->tags;

block/blk-mq.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ EXPORT_SYMBOL_GPL(blk_mq_unquiesce_queue);
312312
void blk_mq_wake_waiters(struct request_queue *q)
313313
{
314314
struct blk_mq_hw_ctx *hctx;
315-
unsigned int i;
315+
unsigned long i;
316316

317317
queue_for_each_hw_ctx(q, hctx, i)
318318
if (blk_mq_hw_queue_mapped(hctx))
@@ -1442,7 +1442,7 @@ static void blk_mq_timeout_work(struct work_struct *work)
14421442
container_of(work, struct request_queue, timeout_work);
14431443
unsigned long next = 0;
14441444
struct blk_mq_hw_ctx *hctx;
1445-
int i;
1445+
unsigned long i;
14461446

14471447
/* A deadlock might occur if a request is stuck requiring a
14481448
* timeout at the same time a queue freeze is waiting
@@ -2143,7 +2143,7 @@ static struct blk_mq_hw_ctx *blk_mq_get_sq_hctx(struct request_queue *q)
21432143
void blk_mq_run_hw_queues(struct request_queue *q, bool async)
21442144
{
21452145
struct blk_mq_hw_ctx *hctx, *sq_hctx;
2146-
int i;
2146+
unsigned long i;
21472147

21482148
sq_hctx = NULL;
21492149
if (blk_mq_has_sqsched(q))
@@ -2171,7 +2171,7 @@ EXPORT_SYMBOL(blk_mq_run_hw_queues);
21712171
void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs)
21722172
{
21732173
struct blk_mq_hw_ctx *hctx, *sq_hctx;
2174-
int i;
2174+
unsigned long i;
21752175

21762176
sq_hctx = NULL;
21772177
if (blk_mq_has_sqsched(q))
@@ -2209,7 +2209,7 @@ EXPORT_SYMBOL(blk_mq_delay_run_hw_queues);
22092209
bool blk_mq_queue_stopped(struct request_queue *q)
22102210
{
22112211
struct blk_mq_hw_ctx *hctx;
2212-
int i;
2212+
unsigned long i;
22132213

22142214
queue_for_each_hw_ctx(q, hctx, i)
22152215
if (blk_mq_hctx_stopped(hctx))
@@ -2248,7 +2248,7 @@ EXPORT_SYMBOL(blk_mq_stop_hw_queue);
22482248
void blk_mq_stop_hw_queues(struct request_queue *q)
22492249
{
22502250
struct blk_mq_hw_ctx *hctx;
2251-
int i;
2251+
unsigned long i;
22522252

22532253
queue_for_each_hw_ctx(q, hctx, i)
22542254
blk_mq_stop_hw_queue(hctx);
@@ -2266,7 +2266,7 @@ EXPORT_SYMBOL(blk_mq_start_hw_queue);
22662266
void blk_mq_start_hw_queues(struct request_queue *q)
22672267
{
22682268
struct blk_mq_hw_ctx *hctx;
2269-
int i;
2269+
unsigned long i;
22702270

22712271
queue_for_each_hw_ctx(q, hctx, i)
22722272
blk_mq_start_hw_queue(hctx);
@@ -2286,7 +2286,7 @@ EXPORT_SYMBOL_GPL(blk_mq_start_stopped_hw_queue);
22862286
void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async)
22872287
{
22882288
struct blk_mq_hw_ctx *hctx;
2289-
int i;
2289+
unsigned long i;
22902290

22912291
queue_for_each_hw_ctx(q, hctx, i)
22922292
blk_mq_start_stopped_hw_queue(hctx, async);
@@ -3446,7 +3446,7 @@ static void blk_mq_exit_hw_queues(struct request_queue *q,
34463446
struct blk_mq_tag_set *set, int nr_queue)
34473447
{
34483448
struct blk_mq_hw_ctx *hctx;
3449-
unsigned int i;
3449+
unsigned long i;
34503450

34513451
queue_for_each_hw_ctx(q, hctx, i) {
34523452
if (i == nr_queue)
@@ -3637,7 +3637,8 @@ static void __blk_mq_free_map_and_rqs(struct blk_mq_tag_set *set,
36373637

36383638
static void blk_mq_map_swqueue(struct request_queue *q)
36393639
{
3640-
unsigned int i, j, hctx_idx;
3640+
unsigned int j, hctx_idx;
3641+
unsigned long i;
36413642
struct blk_mq_hw_ctx *hctx;
36423643
struct blk_mq_ctx *ctx;
36433644
struct blk_mq_tag_set *set = q->tag_set;
@@ -3744,7 +3745,7 @@ static void blk_mq_map_swqueue(struct request_queue *q)
37443745
static void queue_set_hctx_shared(struct request_queue *q, bool shared)
37453746
{
37463747
struct blk_mq_hw_ctx *hctx;
3747-
int i;
3748+
unsigned long i;
37483749

37493750
queue_for_each_hw_ctx(q, hctx, i) {
37503751
if (shared) {
@@ -3844,7 +3845,7 @@ static int blk_mq_alloc_ctxs(struct request_queue *q)
38443845
void blk_mq_release(struct request_queue *q)
38453846
{
38463847
struct blk_mq_hw_ctx *hctx, *next;
3847-
int i;
3848+
unsigned long i;
38483849

38493850
queue_for_each_hw_ctx(q, hctx, i)
38503851
WARN_ON_ONCE(hctx && list_empty(&hctx->hctx_list));
@@ -4362,7 +4363,8 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr)
43624363
{
43634364
struct blk_mq_tag_set *set = q->tag_set;
43644365
struct blk_mq_hw_ctx *hctx;
4365-
int i, ret;
4366+
int ret;
4367+
unsigned long i;
43664368

43674369
if (!set)
43684370
return -EINVAL;
@@ -4738,7 +4740,7 @@ void blk_mq_cancel_work_sync(struct request_queue *q)
47384740
{
47394741
if (queue_is_mq(q)) {
47404742
struct blk_mq_hw_ctx *hctx;
4741-
int i;
4743+
unsigned long i;
47424744

47434745
cancel_delayed_work_sync(&q->requeue_work);
47444746

drivers/block/rnbd/rnbd-clt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ static inline void rnbd_init_hw_queue(struct rnbd_clt_dev *dev,
13431343

13441344
static void rnbd_init_mq_hw_queues(struct rnbd_clt_dev *dev)
13451345
{
1346-
int i;
1346+
unsigned long i;
13471347
struct blk_mq_hw_ctx *hctx;
13481348
struct rnbd_queue *q;
13491349

0 commit comments

Comments
 (0)