Skip to content

Commit e2f2a39

Browse files
YuKuai-huaweiaxboe
authored andcommitted
block, bfq: fix uaf for 'stable_merge_bfqq'
Before commit fd571df ("block, bfq: turn bfqq_data into an array in bfq_io_cq"), process reference is read before bfq_put_stable_ref(), and it's safe if bfq_put_stable_ref() put the last reference, because process reference will be 0 and 'stable_merge_bfqq' won't be accessed in this case. However, the commit changed the order and will cause uaf for 'stable_merge_bfqq'. In order to emphasize that bfq_put_stable_ref() can drop the last reference, fix the problem by moving bfq_put_stable_ref() to the end of bfq_setup_stable_merge(). Fixes: fd571df ("block, bfq: turn bfqq_data into an array in bfq_io_cq") Reported-and-tested-by: Shinichiro Kawasaki <[email protected]> Link: https://lore.kernel.org/linux-block/20230307071448.rzihxbm4jhbf5krj@shindev/ Signed-off-by: Yu Kuai <[email protected]> Reviewed-by: Jan Kara <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent e330622 commit e2f2a39

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

block/bfq-iosched.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2854,11 +2854,11 @@ bfq_setup_stable_merge(struct bfq_data *bfqd, struct bfq_queue *bfqq,
28542854
{
28552855
int proc_ref = min(bfqq_process_refs(bfqq),
28562856
bfqq_process_refs(stable_merge_bfqq));
2857-
struct bfq_queue *new_bfqq;
2857+
struct bfq_queue *new_bfqq = NULL;
28582858

2859-
if (idling_boosts_thr_without_issues(bfqd, bfqq) ||
2860-
proc_ref == 0)
2861-
return NULL;
2859+
bfqq_data->stable_merge_bfqq = NULL;
2860+
if (idling_boosts_thr_without_issues(bfqd, bfqq) || proc_ref == 0)
2861+
goto out;
28622862

28632863
/* next function will take at least one ref */
28642864
new_bfqq = bfq_setup_merge(bfqq, stable_merge_bfqq);
@@ -2873,6 +2873,11 @@ bfq_setup_stable_merge(struct bfq_data *bfqd, struct bfq_queue *bfqq,
28732873
new_bfqq_data->stably_merged = true;
28742874
}
28752875
}
2876+
2877+
out:
2878+
/* deschedule stable merge, because done or aborted here */
2879+
bfq_put_stable_ref(stable_merge_bfqq);
2880+
28762881
return new_bfqq;
28772882
}
28782883

@@ -2933,11 +2938,6 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
29332938
struct bfq_queue *stable_merge_bfqq =
29342939
bfqq_data->stable_merge_bfqq;
29352940

2936-
/* deschedule stable merge, because done or aborted here */
2937-
bfq_put_stable_ref(stable_merge_bfqq);
2938-
2939-
bfqq_data->stable_merge_bfqq = NULL;
2940-
29412941
return bfq_setup_stable_merge(bfqd, bfqq,
29422942
stable_merge_bfqq,
29432943
bfqq_data);

0 commit comments

Comments
 (0)