Update fixes for making ext4 more robust against malicious images
[ext4-patch-queue.git] / add-better-range-checking-for-xattr-value-sizes
blob3b2c9ea15febbf5d0f9be18f0a57347b20f51f2e
1 ext4: limit xattr size to INT_MAX
3 From: Eric Biggers <ebiggers@google.com>
5 ext4 isn't validating the sizes of xattrs.  This is problematic
6 because ->e_value_size is a u32, but ext4_xattr_get() returns an int.
7 A very large size is misinterpreted as an error code, which
8 ext4_get_acl() translates into a bogus ERR_PTR() for which IS_ERR()
9 returns false, causing a crash.
11 Fix this by validating that all xattrs are <= INT_MAX bytes.  Also add
12 explicit checks in ext4_xattr_block_get() and ext4_xattr_ibody_get()
13 just in case the xattr block is corrupted in memory.
15 This issue has been assigned CVE-2018-1095.
17 https://bugzilla.kernel.org/show_bug.cgi?id=199185
18 https://bugzilla.redhat.com/show_bug.cgi?id=1560793
20 Reported-by: Wen Xu <wen.xu@gatech.edu>
21 Signed-off-by: Eric Biggers <ebiggers@google.com>
22 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
23 Cc: stable@vger.kernel.org
24 ---
25  fs/ext4/xattr.c | 11 +++++++++--
26  1 file changed, 9 insertions(+), 2 deletions(-)
28 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
29 index 63656dbafdc4..fea1108c3bea 100644
30 --- a/fs/ext4/xattr.c
31 +++ b/fs/ext4/xattr.c
32 @@ -201,6 +201,9 @@ ext4_xattr_check_entries(struct ext4_xattr_entry *entry, void *end,
33                         u32 size = le32_to_cpu(entry->e_value_size);
34                         void *value;
36 +                       if (size > INT_MAX)
37 +                               return -EFSCORRUPTED;
39                         /*
40                          * The value cannot overlap the names, and the value
41                          * with padding cannot extend beyond 'end'.  Check both
42 @@ -523,8 +526,10 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
43         if (error)
44                 goto cleanup;
45         size = le32_to_cpu(entry->e_value_size);
46 +       error = -ERANGE;
47 +       if (unlikely(size > INT_MAX))
48 +               goto cleanup;
49         if (buffer) {
50 -               error = -ERANGE;
51                 if (size > buffer_size)
52                         goto cleanup;
53                 if (entry->e_value_inum) {
54 @@ -572,8 +577,10 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
55         if (error)
56                 goto cleanup;
57         size = le32_to_cpu(entry->e_value_size);
58 +       error = -ERANGE;
59 +       if (unlikely(size > INT_MAX))
60 +               goto cleanup;
61         if (buffer) {
62 -               error = -ERANGE;
63                 if (size > buffer_size)
64                         goto cleanup;
65                 if (entry->e_value_inum) {