Linux: Fix zfs_prune panics

by protecting against sb->s_shrink eviction on umount with newer kernels

deactivate_locked_super calls shrinker_free and only then
sops->kill_sb cb, resulting in UAF on umount when trying
to reach for the shrinker functions in zpl_prune_sb of
in-umount dataset

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Adam Moss <c@yotes.com>
Signed-off-by: Pavel Snajdr <snajpa@snajpa.net>
Closes #16770
This commit is contained in:
Pavel Snajdr 2024-11-22 00:30:43 +01:00 committed by Tony Hutter
parent a6e1cd1838
commit 0f86fcc2a7

View File

@ -369,7 +369,18 @@ zpl_prune_sb(uint64_t nr_to_scan, void *arg)
struct super_block *sb = (struct super_block *)arg; struct super_block *sb = (struct super_block *)arg;
int objects = 0; int objects = 0;
(void) -zfs_prune(sb, nr_to_scan, &objects); /*
* deactivate_locked_super calls shrinker_free and only then
* sops->kill_sb cb, resulting in UAF on umount when trying to reach
* for the shrinker functions in zpl_prune_sb of in-umount dataset.
* Increment if s_active is not zero, but don't prune if it is -
* umount could be underway.
*/
if (atomic_inc_not_zero(&sb->s_active)) {
(void) -zfs_prune(sb, nr_to_scan, &objects);
atomic_dec(&sb->s_active);
}
} }
const struct super_operations zpl_super_operations = { const struct super_operations zpl_super_operations = {