All of lore.kernel.org
 help / color / mirror / Atom feed
* binfmts.h MAX_ARG_STRINGS excessive value allows heap spraying
@ 2017-03-07 14:44 Leonard den Ottolander
  2017-03-08 17:54 ` Carlos O'Donell
  0 siblings, 1 reply; 17+ messages in thread
From: Leonard den Ottolander @ 2017-03-07 14:44 UTC (permalink / raw)
  To: linux-api-u79uwXL29TY76Z2rM5mHXA

In the article 
https://googleprojectzero.blogspot.nl/2014/08/the-poisoned-nul-byte-2014-edition.html
the author describes launching an attack on an off by one NUL byte bug
in glibc.

He explains that both the memory leak in the option parsing of PolKits
pkexec.c and the excessive value of MAX_ARG_STRINGS in the kernels
include/uapi/linux/binfmts.h (#define MAX_ARG_STRINGS 0x7FFFFFFF)
enabled his attack.

The rationale for that excessive value is a bit odd:

"MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer."

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/include/uapi/linux/binfmts.h?id=607ca46e97a1b6594b29647d98a32d545c24bdff

The fact that the integer is so large makes that on a 32 bit platform
the entire heap can be initialized with values the attacker provides,
given the memory leak in the option parsing of pkexec.c, an approach the
author calls "heap spraying".

(Note that two similar memory leaks exist in the option parsing of
pkexecs sibling pkcheck.c, so pkcheck will also allow an attacker to
heap spray its entire memory on a 32 bit system.)

If you compare http://www.linuxjournal.com/article/6060 you will see
that the TOTAL amount of memory reserved for command line arguments used
to be 32 pages, i.e. 128KiB (#define MAX_ARG_PAGES 32). The amount of
memory reserved for command line arguments in more current kernels is
the multiplication of MAX_ARG_STRINGS and MAX_ARG_STRLEN.

Both the memory leaks in pkexec.c and pkcheck.c seem very severe, but
their impact would be much less if MAX_ARG_STRINGS would hold a sensible
value.

After some experimentation with
$ rpmbuild -ba kernel.spec
on CentOS-7 I've come up with values that allow this kernel compilation.
As this kind of build is probably one of the most demanding actions in
relation to MAX_ARG_STRINGS and MAX_ARG_STRLEN I believe below values to
be sensible and much safer defaults:

#define MAX_ARG_STRLEN 65536
#define MAX_ARG_STRINGS 4096

allow me to build a kernel on a system using those values.

Since the above value of MAX_ARG_STRLEN is half of the current value we
might leave it alone and only alter MAX_ARG_STRINGS, resulting in

--- a/include/uapi/linux/binfmts.h	2016-11-23 21:02:31.000000000 +0100
+++ b/include/uapi/linux/binfmts.h	2017-02-07 15:40:13.548403615 +0100
@@ -12,7 +12,7 @@ struct pt_regs;
  * MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer.
  */
 #define MAX_ARG_STRLEN (PAGE_SIZE * 32)
-#define MAX_ARG_STRINGS 0x7FFFFFFF
+#define MAX_ARG_STRINGS 4096
 
 /* sizeof(linux_binprm->buf) */
 #define BINPRM_BUF_SIZE 128

Filed a bug at https://bugzilla.kernel.org/show_bug.cgi?id=194809 .

Regards,
Leonard.

-- 
mount -t life -o ro /dev/dna /genetic/research

^ permalink raw reply	[flat|nested] 17+ messages in thread
* binfmts.h MAX_ARG_STRINGS excessive value allows heap spraying
@ 2017-03-06 15:29 Leonard den Ottolander
  0 siblings, 0 replies; 17+ messages in thread
From: Leonard den Ottolander @ 2017-03-06 15:29 UTC (permalink / raw)
  To: linux-kernel

In the article 
https://googleprojectzero.blogspot.nl/2014/08/the-poisoned-nul-byte-2014-edition.html
the author describes launching an attack on an off by one NUL byte bug
in glibc.

He explains that both the memory leak in the option parsing of PolKits
pkexec.c and the excessive value of MAX_ARG_STRINGS in the kernels
include/uapi/linux/binfmts.h (#define MAX_ARG_STRINGS 0x7FFFFFFF)
enabled his attack.

The rationale for that excessive value is a bit odd:

"MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer."

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/include/uapi/linux/binfmts.h?id=607ca46e97a1b6594b29647d98a32d545c24bdff

The fact that the integer is so large makes that on a 32 bit platform
the entire heap can be initialized with values the attacker provides,
given the memory leak in the option parsing of pkexec.c, an approach the
author calls "heap spraying".

(Note that two similar memory leaks exist in the option parsing of
pkexecs sibling pkcheck.c, so pkcheck will also allow an attacker to
heap spray its entire memory on a 32 bit system.)

If you compare http://www.linuxjournal.com/article/6060 you will see
that the TOTAL amount of memory reserved for command line arguments used
to be 32 pages, i.e. 128KiB (#define MAX_ARG_PAGES 32). The amount of
memory reserved for command line arguments in more current kernels is
the multiplication of MAX_ARG_STRINGS and MAX_ARG_STRLEN.

Both the memory leaks in pkexec.c and pkcheck.c seem very severe, but
their impact would be much less if MAX_ARG_STRINGS would hold a sensible
value.

After some experimentation with
$ rpmbuild -ba kernel.spec
on CentOS-7 I've come up with values that allow this kernel compilation.
As this kind of build is probably one of the most demanding actions in
relation to MAX_ARG_STRINGS and MAX_ARG_STRLEN I believe below values to
be sensible and much safer defaults:

#define MAX_ARG_STRLEN 65536
#define MAX_ARG_STRINGS 4096

Please let me know if this needs to be filed as a bug somewhere.

Regards,
Leonard.

-- 
mount -t life -o ro /dev/dna /genetic/research

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2017-03-17 13:12 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-07 14:44 binfmts.h MAX_ARG_STRINGS excessive value allows heap spraying Leonard den Ottolander
2017-03-08 17:54 ` Carlos O'Donell
     [not found]   ` <f7f9f60b-0f39-7dce-1778-3aa40ba198ef-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-03-08 18:18     ` Leonard den Ottolander
2017-03-08 18:21       ` Leonard den Ottolander
2017-03-08 20:47       ` Joseph Myers
2017-03-08 21:05       ` Carlos O'Donell
     [not found]         ` <f16cd7f8-f996-cf66-d640-50b0ccee06c7-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-03-09 14:04           ` Leonard den Ottolander
2017-03-09 14:35             ` Carlos O'Donell
2017-03-09 14:14           ` Leonard den Ottolander
2017-03-09 20:34             ` Carlos O'Donell
     [not found]               ` <81d8e14e-e110-4b96-5d45-8bb3b56f4866-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-03-10 12:10                 ` Leonard den Ottolander
2017-03-14  0:51                   ` Carlos O'Donell
     [not found]                     ` <b736f01f-ef0a-56de-bf57-c6d3d74262a4-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-03-17 13:12                       ` Leonard den Ottolander
2017-03-09 23:10             ` Joseph Myers
     [not found]               ` <alpine.DEB.2.20.1703092304110.23273-9YEB1lltEqivcGRMvF24k2I39yigxGEX@public.gmane.org>
2017-03-10  0:01                 ` Carlos O'Donell
2017-03-08 18:48     ` Leonard den Ottolander
  -- strict thread matches above, loose matches on Subject: below --
2017-03-06 15:29 Leonard den Ottolander

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.