[PATCH 0/1 TXAB] LP: #1775856, fs/binfmt_misc.c: do not allow offset overflow

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH 0/1 TXAB] LP: #1775856, fs/binfmt_misc.c: do not allow offset overflow

Thadeu Lima de Souza Cascardo-3
Sorry for the last post, akpm only published this today.

Thadeu Lima de Souza Cascardo (1):
  fs/binfmt_misc.c: do not allow offset overflow

 fs/binfmt_misc.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

--
2.17.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[PATCH Trusty] fs/binfmt_misc.c: do not allow offset overflow

Thadeu Lima de Souza Cascardo-3
BugLink: https://bugs.launchpad.net/bugs/1775856

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@...
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Thadeu Lima de Souza Cascardo <[hidden email]>
Reviewed-by: Andrew Morton <[hidden email]>
Cc: Alexander Viro <[hidden email]>
Cc: <[hidden email]>
Signed-off-by: Andrew Morton <[hidden email]>
Signed-off-by: Linus Torvalds <[hidden email]>
(backported from commit 5cc41e099504b77014358b58567c5ea6293dd220)
Signed-off-by: Thadeu Lima de Souza Cascardo <[hidden email]>
---
 fs/binfmt_misc.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 1c740e152f38..15e39a3ea6cf 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -319,8 +319,13 @@ static Node *create_entry(const char __user *buffer, size_t count)
  char *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;
  e->magic = p;
@@ -341,7 +346,8 @@ static Node *create_entry(const char __user *buffer, size_t count)
  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;
  } else {
  p = strchr(p, del);
--
2.17.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[PATCH Xenial/Artful/Bionic] fs/binfmt_misc.c: do not allow offset overflow

Thadeu Lima de Souza Cascardo-3
In reply to this post by Thadeu Lima de Souza Cascardo-3
BugLink: https://bugs.launchpad.net/bugs/1775856

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@...
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Thadeu Lima de Souza Cascardo <[hidden email]>
Reviewed-by: Andrew Morton <[hidden email]>
Cc: Alexander Viro <[hidden email]>
Cc: <[hidden email]>
Signed-off-by: Andrew Morton <[hidden email]>
Signed-off-by: Linus Torvalds <[hidden email]>
(cherry picked from commit 5cc41e099504b77014358b58567c5ea6293dd220)
Signed-off-by: Thadeu Lima de Souza Cascardo <[hidden email]>
---
 fs/binfmt_misc.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index a7c5a9861bef..8311e8ed76de 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -387,8 +387,13 @@ static Node *create_entry(const char __user *buffer, size_t count)
  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);
@@ -428,7 +433,8 @@ static Node *create_entry(const char __user *buffer, size_t count)
  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) {
--
2.17.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

ACK: [PATCH 0/1 TXAB] LP: #1775856, fs/binfmt_misc.c: do not allow offset overflow

Stefan Bader-2
In reply to this post by Thadeu Lima de Souza Cascardo-3
On 08.06.2018 07:15, Thadeu Lima de Souza Cascardo wrote:
> Sorry for the last post, akpm only published this today.
>
> Thadeu Lima de Souza Cascardo (1):
>   fs/binfmt_misc.c: do not allow offset overflow
>
>  fs/binfmt_misc.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
Acked-by: Stefan Bader <[hidden email]>



--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

ACK: [PATCH 0/1 TXAB] LP: #1775856, fs/binfmt_misc.c: do not allow offset overflow

Marcelo Henrique Cerri
In reply to this post by Thadeu Lima de Souza Cascardo-3
Acked-by: Marcelo Henrique Cerri <[hidden email]>

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team

signature.asc (499 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

APPLIED: [PATCH 0/1 TXAB] LP: #1775856, fs/binfmt_misc.c: do not allow offset overflow

Khalid Elmously
In reply to this post by Thadeu Lima de Souza Cascardo-3
Applied to T,X,A,B


On 2018-06-08 11:15:18 , Thadeu Lima de Souza Cascardo wrote:

> Sorry for the last post, akpm only published this today.
>
> Thadeu Lima de Souza Cascardo (1):
>   fs/binfmt_misc.c: do not allow offset overflow
>
>  fs/binfmt_misc.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> --
> 2.17.0
>
>
> --
> kernel-team mailing list
> [hidden email]
> https://lists.ubuntu.com/mailman/listinfo/kernel-team

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

APPLIED[U]: [PATCH 0/1 TXAB] LP: #1775856, fs/binfmt_misc.c: do not allow offset overflow

Thadeu Lima de Souza Cascardo-3
In reply to this post by Thadeu Lima de Souza Cascardo-3
Applied to unstable master branch.

Thanks.
Cascardo.

Applied-to: unstable/master

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team