ext4: fix potential use after free after remounting with noblock_validity
authorzhangyi (F) <yi.zhang@huawei.com>
Wed, 28 Aug 2019 15:13:24 +0000 (11:13 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 28 Aug 2019 15:13:24 +0000 (11:13 -0400)
commit7727ae52975d4f4ef7ff69ed8e6e25f6a4168158
treed002cc6f188ab3980339fb38d0ae6b684d43ece7
parent4c273352bb4583750bf511fe24fe410610414496
ext4: fix potential use after free after remounting with noblock_validity

Remount process will release system zone which was allocated before if
"noblock_validity" is specified. If we mount an ext4 file system to two
mountpoints with default mount options, and then remount one of them
with "noblock_validity", it may trigger a use after free problem when
someone accessing the other one.

 # mount /dev/sda foo
 # mount /dev/sda bar

User access mountpoint "foo"   |   Remount mountpoint "bar"
                               |
ext4_map_blocks()              |   ext4_remount()
check_block_validity()         |   ext4_setup_system_zone()
ext4_data_block_valid()        |   ext4_release_system_zone()
                               |   free system_blks rb nodes
access system_blks rb nodes    |
trigger use after free         |

This problem can also be reproduced by one mountpint, At the same time,
add_system_zone() can get called during remount as well so there can be
racing ext4_data_block_valid() reading the rbtree at the same time.

This patch add RCU to protect system zone from releasing or building
when doing a remount which inverse current "noblock_validity" mount
option. It assign the rbtree after the whole tree was complete and
do actual freeing after rcu grace period, avoid any intermediate state.

Reported-by: syzbot+1e470567330b7ad711d5@syzkaller.appspotmail.com
Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
fs/ext4/block_validity.c
fs/ext4/ext4.h