[ Upstream commit 05a37c48604c19b50873fd9663f9140c150469d1 ]

Add extra dev extent end check against device boundary.

Signed-off-by: Qu Wenruo <w...@suse.com>
Reviewed-by: David Sterba <dste...@suse.com>
Signed-off-by: David Sterba <dste...@suse.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 fs/btrfs/volumes.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 6e008bd5c8cd1..c20708bfae561 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7411,6 +7411,7 @@ static int verify_one_dev_extent(struct btrfs_fs_info 
*fs_info,
        struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree;
        struct extent_map *em;
        struct map_lookup *map;
+       struct btrfs_device *dev;
        u64 stripe_len;
        bool found = false;
        int ret = 0;
@@ -7460,6 +7461,22 @@ static int verify_one_dev_extent(struct btrfs_fs_info 
*fs_info,
                        physical_offset, devid);
                ret = -EUCLEAN;
        }
+
+       /* Make sure no dev extent is beyond device bondary */
+       dev = btrfs_find_device(fs_info, devid, NULL, NULL);
+       if (!dev) {
+               btrfs_err(fs_info, "failed to find devid %llu", devid);
+               ret = -EUCLEAN;
+               goto out;
+       }
+       if (physical_offset + physical_len > dev->disk_total_bytes) {
+               btrfs_err(fs_info,
+"dev extent devid %llu physical offset %llu len %llu is beyond device boundary 
%llu",
+                         devid, physical_offset, physical_len,
+                         dev->disk_total_bytes);
+               ret = -EUCLEAN;
+               goto out;
+       }
 out:
        free_extent_map(em);
        return ret;
-- 
2.20.1



Reply via email to