diff options
author | Chengguang Xu <cgxu519@zoho.com.cn> | 2019-05-14 06:40:42 +0800 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2019-05-20 10:50:48 +0200 |
commit | f4c3fb8c433f1818da46b720754a5d4a8525fdf0 (patch) | |
tree | 74dda3d85cfd5d1cf864a784c3cacc20c7c94f01 /fs/ext2 | |
parent | 02475de9bb23ed5381f0fb04a84a3c4fad90582d (diff) | |
download | linux-f4c3fb8c433f1818da46b720754a5d4a8525fdf0.tar.bz2 |
ext2: introduce helper for xattr entry validation
Introduce helper function ext2_xattr_entry_valid()
for xattr entry validation and clean up the entry
check related code.
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Chengguang Xu <cgxu519@zoho.com.cn>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/xattr.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index db27260d6a5b..fb2e008d4406 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -144,6 +144,22 @@ ext2_xattr_header_valid(struct ext2_xattr_header *header) return true; } +static bool +ext2_xattr_entry_valid(struct ext2_xattr_entry *entry, size_t end_offs) +{ + size_t size; + + if (entry->e_value_block != 0) + return false; + + size = le32_to_cpu(entry->e_value_size); + if (size > end_offs || + le16_to_cpu(entry->e_value_offs) + size > end_offs) + return false; + + return true; +} + /* * ext2_xattr_get() * @@ -213,14 +229,10 @@ bad_block: error = -ENODATA; goto cleanup; found: - /* check the buffer size */ - if (entry->e_value_block != 0) - goto bad_block; - size = le32_to_cpu(entry->e_value_size); - if (size > inode->i_sb->s_blocksize || - le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) + if (!ext2_xattr_entry_valid(entry, inode->i_sb->s_blocksize)) goto bad_block; + size = le32_to_cpu(entry->e_value_size); if (ext2_xattr_cache_insert(ea_block_cache, bh)) ea_idebug(inode, "cache insert failed"); if (buffer) { @@ -481,12 +493,10 @@ bad_block: if (flags & XATTR_CREATE) goto cleanup; if (!here->e_value_block && here->e_value_size) { - size_t size = le32_to_cpu(here->e_value_size); - - if (le16_to_cpu(here->e_value_offs) + size > - sb->s_blocksize || size > sb->s_blocksize) + if (!ext2_xattr_entry_valid(here, sb->s_blocksize)) goto bad_block; - free += EXT2_XATTR_SIZE(size); + free += EXT2_XATTR_SIZE( + le32_to_cpu(here->e_value_size)); } free += EXT2_XATTR_LEN(name_len); } |