loop: reintroduce global lock for safe loop_validate_file() traversal
authorTetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Tue, 6 Jul 2021 14:40:34 +0000 (23:40 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Aug 2021 10:47:52 +0000 (12:47 +0200)
commit56a5e590b31eec87c20763d331d88b0e36c564cd
tree34836811fac2cf3f6a7f2ec2aac30432df01f48b
parentfcc99d41954f8deba6863326db0d5bfeee797547
loop: reintroduce global lock for safe loop_validate_file() traversal

[ Upstream commit 3ce6e1f662a910970880188ea7bfd00542bd3934 ]

Commit 6cc8e7430801fa23 ("loop: scale loop device by introducing per
device lock") re-opened a race window for NULL pointer dereference at
loop_validate_file() where commit 310ca162d779efee ("block/loop: Use
global lock for ioctl() operation.") has closed.

Although we need to guarantee that other loop devices will not change
during traversal, we can't take remote "struct loop_device"->lo_mutex
inside loop_validate_file() in order to avoid AB-BA deadlock. Therefore,
introduce a global lock dedicated for loop_validate_file() which is
conditionally taken before local "struct loop_device"->lo_mutex is taken.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Fixes: 6cc8e7430801fa23 ("loop: scale loop device by introducing per device lock")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/block/loop.c