When we end up getting an unsupported zone model in
btrfs_get_dev_zone_info() the default error handling case frees all
allocated resources, but "zones" was already freed resulting in a
double-free and "zone_info" is already assigned to device->zone_info
resulting in a potential use-after-free.

For the double free we could also set 'zones = NULL' after freeing, but I
think this way is more readable.

Reported-by: kernel test robot <l...@intel.com>
Reported-by: Julia Lawall <julia.law...@lip6.fr>
Fixes: 9e802babe329 ("btrfs: allow zoned mode on non-zoned block devices")
Signed-off-by: Johannes Thumshirn <johannes.thumsh...@wdc.com>
---
 fs/btrfs/zoned.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 362df27040ff..fd953ec848e6 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -425,7 +425,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
                                 bdev_zoned_model(bdev),
                                 rcu_str_deref(device->name));
                ret = -EOPNOTSUPP;
-               goto out;
+               goto out_free_zone_info;
        }
 
        btrfs_info_in_rcu(fs_info,
@@ -437,9 +437,11 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
 
 out:
        kfree(zones);
+out_free_zone_info:
        bitmap_free(zone_info->empty_zones);
        bitmap_free(zone_info->seq_zones);
        kfree(zone_info);
+       device->zone_info = NULL;
 
        return ret;
 }
-- 
2.26.2

Reply via email to