Skip to content

Commit

Permalink
ext4: add bounds checking to ext4_xattr_find_entry()
Browse files Browse the repository at this point in the history
Add some paranoia checks to make sure we don't stray beyond the end of
the valid memory region containing ext4 xattr entries while we are
scanning for a match.

Also rename the function to xattr_find_entry() since it is static and
thus only used in fs/ext4/xattr.c

Signed-off-by: Theodore Ts'o <[email protected]>
Cc: [email protected]
  • Loading branch information
tytso committed Mar 31, 2018
1 parent de05ca8 commit 9496005
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions fs/ext4/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,18 +276,22 @@ __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
__xattr_check_inode((inode), (header), (end), __func__, __LINE__)

static int
ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
const char *name, int sorted)
xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry,
void *end, int name_index, const char *name, int sorted)
{
struct ext4_xattr_entry *entry;
struct ext4_xattr_entry *entry, *next;
size_t name_len;
int cmp = 1;

if (name == NULL)
return -EINVAL;
name_len = strlen(name);
entry = *pentry;
for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
for (entry = *pentry; !IS_LAST_ENTRY(entry); entry = next) {
next = EXT4_XATTR_NEXT(entry);
if ((void *) next >= end) {
EXT4_ERROR_INODE(inode, "corrupted xattr entries");
return -EFSCORRUPTED;
}
cmp = name_index - entry->e_name_index;
if (!cmp)
cmp = name_len - entry->e_name_len;
Expand Down Expand Up @@ -509,6 +513,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
struct buffer_head *bh = NULL;
struct ext4_xattr_entry *entry;
size_t size;
void *end;
int error;
struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode);

Expand All @@ -530,7 +535,8 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
goto cleanup;
ext4_xattr_block_cache_insert(ea_block_cache, bh);
entry = BFIRST(bh);
error = ext4_xattr_find_entry(&entry, name_index, name, 1);
end = bh->b_data + bh->b_size;
error = xattr_find_entry(inode, &entry, end, name_index, name, 1);
if (error)
goto cleanup;
size = le32_to_cpu(entry->e_value_size);
Expand Down Expand Up @@ -579,7 +585,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
if (error)
goto cleanup;
entry = IFIRST(header);
error = ext4_xattr_find_entry(&entry, name_index, name, 0);
error = xattr_find_entry(inode, &entry, end, name_index, name, 0);
if (error)
goto cleanup;
size = le32_to_cpu(entry->e_value_size);
Expand Down Expand Up @@ -1808,8 +1814,8 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
bs->s.first = BFIRST(bs->bh);
bs->s.end = bs->bh->b_data + bs->bh->b_size;
bs->s.here = bs->s.first;
error = ext4_xattr_find_entry(&bs->s.here, i->name_index,
i->name, 1);
error = xattr_find_entry(inode, &bs->s.here, bs->s.end,
i->name_index, i->name, 1);
if (error && error != -ENODATA)
goto cleanup;
bs->s.not_found = error;
Expand Down Expand Up @@ -2168,8 +2174,8 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
if (error)
return error;
/* Find the named attribute. */
error = ext4_xattr_find_entry(&is->s.here, i->name_index,
i->name, 0);
error = xattr_find_entry(inode, &is->s.here, is->s.end,
i->name_index, i->name, 0);
if (error && error != -ENODATA)
return error;
is->s.not_found = error;
Expand Down

0 comments on commit 9496005

Please sign in to comment.