Skip to content

Commit 9e3041f

Browse files
jdmfrakpm00
authored andcommitted
ocfs2: add bounds checking to ocfs2_xattr_find_entry()
Add a paranoia check to make sure it doesn't stray beyond valid memory region containing ocfs2 xattr entries when scanning for a match. It will prevent out-of-bound access in case of crafted images. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ferry Meng <[email protected]> Signed-off-by: Joseph Qi <[email protected]> Reported-by: lei lu <[email protected]> Reviewed-by: Joseph Qi <[email protected]> Cc: Mark Fasheh <[email protected]> Cc: Joel Becker <[email protected]> Cc: Junxiao Bi <[email protected]> Cc: Changwei Ge <[email protected]> Cc: Gang He <[email protected]> Cc: Jun Piao <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 82a9d6b commit 9e3041f

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

fs/ocfs2/xattr.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ ssize_t ocfs2_listxattr(struct dentry *dentry,
10621062
return i_ret + b_ret;
10631063
}
10641064

1065-
static int ocfs2_xattr_find_entry(int name_index,
1065+
static int ocfs2_xattr_find_entry(struct inode *inode, int name_index,
10661066
const char *name,
10671067
struct ocfs2_xattr_search *xs)
10681068
{
@@ -1076,6 +1076,10 @@ static int ocfs2_xattr_find_entry(int name_index,
10761076
name_len = strlen(name);
10771077
entry = xs->here;
10781078
for (i = 0; i < le16_to_cpu(xs->header->xh_count); i++) {
1079+
if ((void *)entry >= xs->end) {
1080+
ocfs2_error(inode->i_sb, "corrupted xattr entries");
1081+
return -EFSCORRUPTED;
1082+
}
10791083
cmp = name_index - ocfs2_xattr_get_type(entry);
10801084
if (!cmp)
10811085
cmp = name_len - entry->xe_name_len;
@@ -1166,7 +1170,7 @@ static int ocfs2_xattr_ibody_get(struct inode *inode,
11661170
xs->base = (void *)xs->header;
11671171
xs->here = xs->header->xh_entries;
11681172

1169-
ret = ocfs2_xattr_find_entry(name_index, name, xs);
1173+
ret = ocfs2_xattr_find_entry(inode, name_index, name, xs);
11701174
if (ret)
11711175
return ret;
11721176
size = le64_to_cpu(xs->here->xe_value_size);
@@ -2698,7 +2702,7 @@ static int ocfs2_xattr_ibody_find(struct inode *inode,
26982702

26992703
/* Find the named attribute. */
27002704
if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) {
2701-
ret = ocfs2_xattr_find_entry(name_index, name, xs);
2705+
ret = ocfs2_xattr_find_entry(inode, name_index, name, xs);
27022706
if (ret && ret != -ENODATA)
27032707
return ret;
27042708
xs->not_found = ret;
@@ -2833,7 +2837,7 @@ static int ocfs2_xattr_block_find(struct inode *inode,
28332837
xs->end = (void *)(blk_bh->b_data) + blk_bh->b_size;
28342838
xs->here = xs->header->xh_entries;
28352839

2836-
ret = ocfs2_xattr_find_entry(name_index, name, xs);
2840+
ret = ocfs2_xattr_find_entry(inode, name_index, name, xs);
28372841
} else
28382842
ret = ocfs2_xattr_index_block_find(inode, blk_bh,
28392843
name_index,

0 commit comments

Comments
 (0)