diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 9f2d412fc560e1e3d08eb8d4293f4a7309dae90f..631bc2543d749ed2399170b2812b191170c1cbf2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1992,6 +1992,17 @@ static int loop_add(int i) struct gendisk *disk; int err; + /* + * i << part_shift is actually used as the first_minor. + * So here should avoid i << part_shift overflow. + * And, MKDEV() expect that the max bits of + * first_minor is 20. + */ + if (i > 0 && i > MINORMASK >> part_shift) { + err = -EINVAL; + goto out; + } + err = -ENOMEM; lo = kzalloc(sizeof(*lo), GFP_KERNEL); if (!lo) @@ -2011,7 +2022,8 @@ static int loop_add(int i) if (err == -ENOSPC) err = -EEXIST; } else { - err = idr_alloc(&loop_index_idr, lo, 0, 0, GFP_KERNEL); + err = idr_alloc(&loop_index_idr, lo, 0, + (MINORMASK >> part_shift) + 1, GFP_KERNEL); } mutex_unlock(&loop_ctl_mutex); if (err < 0)