The XATTR_ITEM is a type of a directory item so we use the common
validator helper. We have to adjust the limits because of potential
data_len (ie. the xattr value), which is otherwise 0 for other directory
items.

Signed-off-by: David Sterba <[email protected]>
---
 fs/btrfs/dir-item.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index 2b00dd746118..a48d496e63e4 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -498,6 +498,7 @@ bool btrfs_is_name_len_valid(struct extent_buffer *leaf, 
int slot,
 {
        struct btrfs_fs_info *fs_info = leaf->fs_info;
        struct btrfs_key key;
+       struct btrfs_dir_item *di;
        u32 read_start;
        u32 read_end;
        u32 item_start;
@@ -515,8 +516,17 @@ bool btrfs_is_name_len_valid(struct extent_buffer *leaf, 
int slot,
        btrfs_item_key_to_cpu(leaf, &key, slot);
 
        switch (key.type) {
-       case BTRFS_DIR_ITEM_KEY:
        case BTRFS_XATTR_ITEM_KEY:
+               /*
+                * XATTR_ITEM could contain data so the item_end would not
+                * match read_end as for other item types. Artificially lower
+                * the upper bound so we check just name_len. We have to trust
+                * the data_len value here, but if it's too big the validation
+                * fails so it's safer than increasing read_end.
+                */
+               di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
+               item_end -= btrfs_dir_data_len(leaf, di);
+       case BTRFS_DIR_ITEM_KEY:
        case BTRFS_DIR_INDEX_KEY:
                size = sizeof(struct btrfs_dir_item);
                break;
-- 
2.13.0

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to