From: Ferry Meng mengferry@linux.alibaba.com
mainline inclusion from mainline-v6.11-rc1 commit af77c4fc1871847b528d58b7fdafb4aa1f6a9262 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAG8SI CVE: CVE-2024-41016
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
xattr in ocfs2 maybe 'non-indexed', which saved with additional space requested. It's better to check if the memory is out of bound before memcmp, although this possibility mainly comes from crafted poisonous images.
Link: https://lkml.kernel.org/r/20240520024024.1976129-2-joseph.qi@linux.alibaba.c... Signed-off-by: Ferry Meng mengferry@linux.alibaba.com Signed-off-by: Joseph Qi joseph.qi@linux.alibaba.com Reported-by: lei lu llfamsec@gmail.com Reviewed-by: Joseph Qi joseph.qi@linux.alibaba.com Cc: Changwei Ge gechangwei@live.cn Cc: Gang He ghe@suse.com Cc: Joel Becker jlbec@evilplan.org Cc: Jun Piao piaojun@huawei.com Cc: Junxiao Bi junxiao.bi@oracle.com Cc: Mark Fasheh mark@fasheh.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Yu Liao liaoyu15@huawei.com --- fs/ocfs2/xattr.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 10df2e1dfef7..fbbb2a88ffec 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -1074,7 +1074,7 @@ static int ocfs2_xattr_find_entry(int name_index, { struct ocfs2_xattr_entry *entry; size_t name_len; - int i, cmp = 1; + int i, name_offset, cmp = 1;
if (name == NULL) return -EINVAL; @@ -1085,10 +1085,15 @@ static int ocfs2_xattr_find_entry(int name_index, cmp = name_index - ocfs2_xattr_get_type(entry); if (!cmp) cmp = name_len - entry->xe_name_len; - if (!cmp) - cmp = memcmp(name, (xs->base + - le16_to_cpu(entry->xe_name_offset)), - name_len); + if (!cmp) { + name_offset = le16_to_cpu(entry->xe_name_offset); + if ((xs->base + name_offset + name_len) > xs->end) { + ocfs2_error(inode->i_sb, + "corrupted xattr entries"); + return -EFSCORRUPTED; + } + cmp = memcmp(name, (xs->base + name_offset), name_len); + } if (cmp == 0) break; entry += 1;