Add extra dev extent end check against device boundary.

Signed-off-by: Qu Wenruo <w...@suse.com>
---
 fs/btrfs/volumes.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index bf0b2c16847a..9fb40e30be6a 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7492,6 +7492,7 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info 
*fs_info)
        while (1) {
                struct extent_buffer *leaf = path->nodes[0];
                struct btrfs_dev_extent *dext;
+               struct btrfs_device *dev;
                int slot = path->slots[0];
                u64 chunk_offset;
                u64 physical_offset;
@@ -7517,6 +7518,22 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info 
*fs_info)
                        goto out;
                }
 
+               /* 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;
+               }
+
                ret = verify_one_dev_extent(fs_info, chunk_offset, devid,
                                            physical_offset, physical_len);
                if (ret < 0)
-- 
2.19.0

Reply via email to