]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ext4: add corruption check in ext4_xattr_set_entry()
authorTheodore Ts'o <tytso@mit.edu>
Wed, 13 Jun 2018 04:23:11 +0000 (00:23 -0400)
committerBrian Maly <brian.maly@oracle.com>
Tue, 19 Mar 2019 16:24:34 +0000 (12:24 -0400)
commit 5369a762c882c0b6e9599e4ebbb3a9ba9eee7e2d upstream.

In theory this should have been caught earlier when the xattr list was
verified, but in case it got missed, it's simple enough to add check
to make sure we don't overrun the xattr buffer.

This addresses CVE-2018-10879.

https://bugzilla.kernel.org/show_bug.cgi?id=200001

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Cc: stable@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 0dc148230f3827f49b1e2a72d14cbad0c5c63e86)

Orabug: 29437127
CVE: CVE-2018-10879

Signed-off-by: John Donnelly <John.P.Donnelly@oracle.com>
Reviewed-by: Jack Vogel <jack.vogel@oracle.com>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
Conflicts:
fs/ext4/xattr.c

Signed-off-by: Brian Maly <brian.maly@oracle.com>
fs/ext4/xattr.c

index 47011b07876bd348a04da9e6ad84f60dba702867..72721c8c3585d07f3b8b7b7b4de3cf0e491b186f 100644 (file)
@@ -618,12 +618,17 @@ static size_t ext4_xattr_free_space(struct ext4_xattr_entry *last,
 static int
 ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s)
 {
-       struct ext4_xattr_entry *last;
+       struct ext4_xattr_entry *last, *next;
        size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
 
        /* Compute min_offs and last. */
        last = s->first;
-       for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
+       for (; !IS_LAST_ENTRY(last); last = next) {
+               next = EXT4_XATTR_NEXT(last);
+               if ((void *)next >= s->end) {
+                       printk(KERN_ERR "ext4: corrupted xattr entries");
+                       return -EFSCORRUPTED;
+               }
                if (!last->e_value_block && last->e_value_size) {
                        size_t offs = le16_to_cpu(last->e_value_offs);
                        if (offs < min_offs)