From 3091f4aaadda0adcbdd59fd4abc35fcc90ab96f4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 24 Jun 2018 22:24:03 +0800 Subject: [PATCH] 4.4-stable patches added patches: fs-binfmt_misc.c-do-not-allow-offset-overflow.patch --- ..._misc.c-do-not-allow-offset-overflow.patch | 80 +++++++++++++++++++ queue-4.4/series | 1 + 2 files changed, 81 insertions(+) create mode 100644 queue-4.4/fs-binfmt_misc.c-do-not-allow-offset-overflow.patch diff --git a/queue-4.4/fs-binfmt_misc.c-do-not-allow-offset-overflow.patch b/queue-4.4/fs-binfmt_misc.c-do-not-allow-offset-overflow.patch new file mode 100644 index 00000000000..61a8aeb4023 --- /dev/null +++ b/queue-4.4/fs-binfmt_misc.c-do-not-allow-offset-overflow.patch @@ -0,0 +1,80 @@ +From 5cc41e099504b77014358b58567c5ea6293dd220 Mon Sep 17 00:00:00 2001 +From: Thadeu Lima de Souza Cascardo +Date: Thu, 7 Jun 2018 17:11:01 -0700 +Subject: fs/binfmt_misc.c: do not allow offset overflow + +From: Thadeu Lima de Souza Cascardo + +commit 5cc41e099504b77014358b58567c5ea6293dd220 upstream. + +WHen registering a new binfmt_misc handler, it is possible to overflow +the offset to get a negative value, which might crash the system, or +possibly leak kernel data. + +Here is a crash log when 2500000000 was used as an offset: + + BUG: unable to handle kernel paging request at ffff989cfd6edca0 + IP: load_misc_binary+0x22b/0x470 [binfmt_misc] + PGD 1ef3e067 P4D 1ef3e067 PUD 0 + Oops: 0000 [#1] SMP NOPTI + Modules linked in: binfmt_misc kvm_intel ppdev kvm irqbypass joydev input_leds serio_raw mac_hid parport_pc qemu_fw_cfg parpy + CPU: 0 PID: 2499 Comm: bash Not tainted 4.15.0-22-generic #24-Ubuntu + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.1-1 04/01/2014 + RIP: 0010:load_misc_binary+0x22b/0x470 [binfmt_misc] + Call Trace: + search_binary_handler+0x97/0x1d0 + do_execveat_common.isra.34+0x667/0x810 + SyS_execve+0x31/0x40 + do_syscall_64+0x73/0x130 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 + +Use kstrtoint instead of simple_strtoul. It will work as the code +already set the delimiter byte to '\0' and we only do it when the field +is not empty. + +Tested with offsets -1, 2500000000, UINT_MAX and INT_MAX. Also tested +with examples documented at Documentation/admin-guide/binfmt-misc.rst +and other registrations from packages on Ubuntu. + +Link: http://lkml.kernel.org/r/20180529135648.14254-1-cascardo@canonical.com +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Thadeu Lima de Souza Cascardo +Reviewed-by: Andrew Morton +Cc: Alexander Viro +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/binfmt_misc.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/fs/binfmt_misc.c ++++ b/fs/binfmt_misc.c +@@ -369,8 +369,13 @@ static Node *create_entry(const char __u + s = strchr(p, del); + if (!s) + goto einval; +- *s++ = '\0'; +- e->offset = simple_strtoul(p, &p, 10); ++ *s = '\0'; ++ if (p != s) { ++ int r = kstrtoint(p, 10, &e->offset); ++ if (r != 0 || e->offset < 0) ++ goto einval; ++ } ++ p = s; + if (*p++) + goto einval; + pr_debug("register: offset: %#x\n", e->offset); +@@ -410,7 +415,8 @@ static Node *create_entry(const char __u + if (e->mask && + string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size) + goto einval; +- if (e->size + e->offset > BINPRM_BUF_SIZE) ++ if (e->size > BINPRM_BUF_SIZE || ++ BINPRM_BUF_SIZE - e->size < e->offset) + goto einval; + pr_debug("register: magic/mask length: %i\n", e->size); + if (USE_DEBUG) { diff --git a/queue-4.4/series b/queue-4.4/series index ba9907ab05f..ab7aad6ceac 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -22,3 +22,4 @@ libata-zpodd-make-arrays-cdb-static-reduces-object-code-size.patch libata-zpodd-small-read-overflow-in-eject_tray.patch libata-drop-sandisk-sd7ub3q-g1001-nolpm-quirk.patch w1-mxc_w1-enable-clock-before-calling-clk_get_rate-on-it.patch +fs-binfmt_misc.c-do-not-allow-offset-overflow.patch -- 2.47.3