]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.18.114/fs-binfmt_misc.c-do-not-allow-offset-overflow.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.18.114 / fs-binfmt_misc.c-do-not-allow-offset-overflow.patch
1 From 5cc41e099504b77014358b58567c5ea6293dd220 Mon Sep 17 00:00:00 2001
2 From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
3 Date: Thu, 7 Jun 2018 17:11:01 -0700
4 Subject: fs/binfmt_misc.c: do not allow offset overflow
5
6 From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
7
8 commit 5cc41e099504b77014358b58567c5ea6293dd220 upstream.
9
10 WHen registering a new binfmt_misc handler, it is possible to overflow
11 the offset to get a negative value, which might crash the system, or
12 possibly leak kernel data.
13
14 Here is a crash log when 2500000000 was used as an offset:
15
16 BUG: unable to handle kernel paging request at ffff989cfd6edca0
17 IP: load_misc_binary+0x22b/0x470 [binfmt_misc]
18 PGD 1ef3e067 P4D 1ef3e067 PUD 0
19 Oops: 0000 [#1] SMP NOPTI
20 Modules linked in: binfmt_misc kvm_intel ppdev kvm irqbypass joydev input_leds serio_raw mac_hid parport_pc qemu_fw_cfg parpy
21 CPU: 0 PID: 2499 Comm: bash Not tainted 4.15.0-22-generic #24-Ubuntu
22 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.1-1 04/01/2014
23 RIP: 0010:load_misc_binary+0x22b/0x470 [binfmt_misc]
24 Call Trace:
25 search_binary_handler+0x97/0x1d0
26 do_execveat_common.isra.34+0x667/0x810
27 SyS_execve+0x31/0x40
28 do_syscall_64+0x73/0x130
29 entry_SYSCALL_64_after_hwframe+0x3d/0xa2
30
31 Use kstrtoint instead of simple_strtoul. It will work as the code
32 already set the delimiter byte to '\0' and we only do it when the field
33 is not empty.
34
35 Tested with offsets -1, 2500000000, UINT_MAX and INT_MAX. Also tested
36 with examples documented at Documentation/admin-guide/binfmt-misc.rst
37 and other registrations from packages on Ubuntu.
38
39 Link: http://lkml.kernel.org/r/20180529135648.14254-1-cascardo@canonical.com
40 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
41 Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
42 Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
43 Cc: Alexander Viro <viro@zeniv.linux.org.uk>
44 Cc: <stable@vger.kernel.org>
45 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
46 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
47 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
48
49 ---
50 fs/binfmt_misc.c | 12 +++++++++---
51 1 file changed, 9 insertions(+), 3 deletions(-)
52
53 --- a/fs/binfmt_misc.c
54 +++ b/fs/binfmt_misc.c
55 @@ -334,8 +334,13 @@ static Node *create_entry(const char __u
56 char *s = strchr(p, del);
57 if (!s)
58 goto Einval;
59 - *s++ = '\0';
60 - e->offset = simple_strtoul(p, &p, 10);
61 + *s = '\0';
62 + if (p != s) {
63 + int r = kstrtoint(p, 10, &e->offset);
64 + if (r != 0 || e->offset < 0)
65 + goto Einval;
66 + }
67 + p = s;
68 if (*p++)
69 goto Einval;
70 e->magic = p;
71 @@ -356,7 +361,8 @@ static Node *create_entry(const char __u
72 if (e->mask &&
73 string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size)
74 goto Einval;
75 - if (e->size + e->offset > BINPRM_BUF_SIZE)
76 + if (e->size > BINPRM_BUF_SIZE ||
77 + BINPRM_BUF_SIZE - e->size < e->offset)
78 goto Einval;
79 } else {
80 p = strchr(p, del);