]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ocfs2: strict bound check before memcmp in ocfs2_xattr_find_entry()
authorFerry Meng <mengferry@linux.alibaba.com>
Mon, 20 May 2024 02:40:24 +0000 (10:40 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 25 Jun 2024 05:24:55 +0000 (22:24 -0700)
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.com
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>
fs/ocfs2/xattr.c

index 8aea94c907397948c371573448b9d3b9d312f970..35c0cc2a51af82daf9241624a50cf37a96850d2a 100644 (file)
@@ -1068,7 +1068,7 @@ static int ocfs2_xattr_find_entry(struct inode *inode, 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;
@@ -1083,10 +1083,15 @@ static int ocfs2_xattr_find_entry(struct inode *inode, 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;