Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Ubuntu Kernel Team (http://www.linux-archive.org/ubuntu-kernel-team/)
-   -   UBUNTU: SAUCE: x86: brk away from exec rand area (http://www.linux-archive.org/ubuntu-kernel-team/309934-ubuntu-sauce-x86-brk-away-exec-rand-area.html)

Kees Cook 01-15-2010 07:41 PM

UBUNTU: SAUCE: x86: brk away from exec rand area
 
This is a fix for the NX emulation patch to force the brk area well outside
of the exec randomization area to avoid future allocation or brk growth
collisions. Normally this isn't a problem, except when the text region
has been loaded from a PIE binary and the CS limit can't be put just above
bss.

Additionally, the nx-emulation patch was still randomizing addresses even when
randomize_va_space was disabled, which would cause collisions even faster if
someone tried to disable randomization.

BugLink: http://bugs.launchpad.net/bugs/452175

Signed-off-by: Kees Cook <kees.cook@canonical.com>
---
fs/binfmt_elf.c | 10 ++++++++++
mm/mmap.c | 11 ++++++++---
2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index b10acea..73594b9 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -978,6 +978,16 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
#ifdef arch_randomize_brk
if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1))
current->mm->brk = current->mm->start_brk =
+# ifdef CONFIG_X86_32
+ /* in the case of NX emulation, shove the brk
+ segment way out of the way of the exec
+ randomization area, since it can collide with
+ future allocations if not. */
+ ( (current->mm->get_unmapped_exec_area ==
+ arch_get_unmapped_exec_area) &&
+ (current->mm->brk < 0x08000000)
+ ? (TASK_SIZE/6) : 0) +
+# endif
arch_randomize_brk(current->mm);
#endif

diff --git a/mm/mmap.c b/mm/mmap.c
index 814b95f..17ed65d 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1516,8 +1516,11 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
if (flags & MAP_FIXED)
return addr;

- if (!addr)
- addr = randomize_range(SHLIB_BASE, 0x01000000, len);
+ if (!addr) {
+ addr = SHLIB_BASE;
+ if ((current->flags & PF_RANDOMIZE) && randomize_va_space)
+ addr = randomize_range(addr, 0x01000000, len);
+ }

if (addr) {
addr = PAGE_ALIGN(addr);
@@ -1545,7 +1548,9 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
* Up until the brk area we randomize addresses
* as much as possible:
*/
- if (addr >= 0x01000000) {
+ if ((current->flags & PF_RANDOMIZE) &&
+ randomize_va_space &&
+ addr >= 0x01000000) {
tmp = randomize_range(0x01000000,
PAGE_ALIGN(max(mm->start_brk,
(unsigned long)0x08000000)), len);
--
1.6.5


--
Kees Cook
Ubuntu Security Team

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team

Jeremy Kerr 01-15-2010 11:04 PM

UBUNTU: SAUCE: x86: brk away from exec rand area
 
Hi Kees,

> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index b10acea..73594b9 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -978,6 +978,16 @@ static int load_elf_binary(struct linux_binprm *bprm,
> struct pt_regs *regs) #ifdef arch_randomize_brk
> if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1))
> current->mm->brk = current->mm->start_brk =
> +# ifdef CONFIG_X86_32
> + /* in the case of NX emulation, shove the brk
> + segment way out of the way of the exec
> + randomization area, since it can collide with
> + future allocations if not. */
> + ( (current->mm->get_unmapped_exec_area ==
> + arch_get_unmapped_exec_area) &&
> + (current->mm->brk < 0x08000000)
> + ? (TASK_SIZE/6) : 0) +
> +# endif
> arch_randomize_brk(current->mm);

Seeing as this is arch specific, it might be best to put it in
arch_randomize_brk, if possible.

Cheers,


Jeremy

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team

Kees Cook 01-15-2010 11:18 PM

UBUNTU: SAUCE: x86: brk away from exec rand area
 
Hi Jeremy,

On Sat, Jan 16, 2010 at 11:04:05AM +1100, Jeremy Kerr wrote:
> > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> > index b10acea..73594b9 100644
> > --- a/fs/binfmt_elf.c
> > +++ b/fs/binfmt_elf.c
> > @@ -978,6 +978,16 @@ static int load_elf_binary(struct linux_binprm *bprm,
> > struct pt_regs *regs) #ifdef arch_randomize_brk
> > if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1))
> > current->mm->brk = current->mm->start_brk =
> > +# ifdef CONFIG_X86_32
> > + /* in the case of NX emulation, shove the brk
> > + segment way out of the way of the exec
> > + randomization area, since it can collide with
> > + future allocations if not. */
> > + ( (current->mm->get_unmapped_exec_area ==
> > + arch_get_unmapped_exec_area) &&
> > + (current->mm->brk < 0x08000000)
> > + ? (TASK_SIZE/6) : 0) +
> > +# endif
> > arch_randomize_brk(current->mm);
>
> Seeing as this is arch specific, it might be best to put it in
> arch_randomize_brk, if possible.

arch_randomize_brk() is shared by x86 and x86_64, so if I moved it, it
would still carry the #ifdef CONFIG_X86_32. I can certainly move it,
but I felt it was more readable closer to the brk-calculation logic of
the ELF loader. (Nothing in the cs-limit patch[1] currently modifies
arch/x86/kernel/process.c, so I was also trying to avoid touching even
more files than it already does.)

Thanks,

-Kees

[1] http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-lucid.git;a=commitdiff;h=32a306aa2738c3d0a3f1c451b 1a179358f02abf2

--
Kees Cook
Ubuntu Security Team

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team

Kees Cook 01-19-2010 05:31 PM

UBUNTU: SAUCE: x86: brk away from exec rand area
 
This is a fix for the NX emulation patch to force the brk area well
outside of the exec randomization area to avoid future allocation or brk
growth collisions. Normally this isn't a problem, except when the text
region has been loaded from a PIE binary and the CS limit can't be put
just above bss.

Additionally, the nx-emulation patch was still randomizing addresses
even when randomize_va_space was disabled, which would cause collisions
even faster if someone tried to disable randomization.

BugLink: http://bugs.launchpad.net/bugs/452175

Signed-off-by: Kees Cook <kees.cook at canonical.com>
---
arch/x86/kernel/process.c | 12 +++++++++++-
mm/mmap.c | 11 ++++++++---
2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 5284cd2..bf5c156 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -607,6 +607,16 @@ unsigned long arch_align_stack(unsigned long sp)
unsigned long arch_randomize_brk(struct mm_struct *mm)
{
unsigned long range_end = mm->brk + 0x02000000;
- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+ unsigned long bump = 0;
+#ifdef CONFIG_X86_32
+ /* in the case of NX emulation, shove the brk segment way out of the
+ way of the exec randomization area, since it can collide with
+ future allocations if not. */
+ if ( (mm->get_unmapped_exec_area == arch_get_unmapped_exec_area) &&
+ (mm->brk < 0x08000000) ) {
+ bump = (TASK_SIZE/6);
+ }
+#endif
+ return bump + (randomize_range(mm->brk, range_end, 0) ? : mm->brk);
}

diff --git a/mm/mmap.c b/mm/mmap.c
index a1483c5..c6d7e53 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1500,8 +1500,11 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
if (flags & MAP_FIXED)
return addr;

- if (!addr)
- addr = randomize_range(SHLIB_BASE, 0x01000000, len);
+ if (!addr) {
+ addr = SHLIB_BASE;
+ if ((current->flags & PF_RANDOMIZE) && randomize_va_space)
+ addr = randomize_range(addr, 0x01000000, len);
+ }

if (addr) {
addr = PAGE_ALIGN(addr);
@@ -1529,7 +1532,9 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
* Up until the brk area we randomize addresses
* as much as possible:
*/
- if (addr >= 0x01000000) {
+ if ((current->flags & PF_RANDOMIZE) &&
+ randomize_va_space &&
+ addr >= 0x01000000) {
tmp = randomize_range(0x01000000,
PAGE_ALIGN(max(mm->start_brk,
(unsigned long)0x08000000)), len);
--
1.6.5

--
Kees Cook
Ubuntu Security Team

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team

Andy Whitcroft 01-19-2010 05:40 PM

UBUNTU: SAUCE: x86: brk away from exec rand area
 
On Tue, Jan 19, 2010 at 10:31:34AM -0800, Kees Cook wrote:
> This is a fix for the NX emulation patch to force the brk area well
> outside of the exec randomization area to avoid future allocation or brk
> growth collisions. Normally this isn't a problem, except when the text
> region has been loaded from a PIE binary and the CS limit can't be put
> just above bss.
>
> Additionally, the nx-emulation patch was still randomizing addresses
> even when randomize_va_space was disabled, which would cause collisions
> even faster if someone tried to disable randomization.
>
> BugLink: http://bugs.launchpad.net/bugs/452175
>
> Signed-off-by: Kees Cook <kees.cook at canonical.com>

Acked-by: Andy Whitcroft <apw@canonical.com>

-apw

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team

Stefan Bader 01-22-2010 01:04 PM

UBUNTU: SAUCE: x86: brk away from exec rand area
 
I d love to understand that foo better, maybe we can do a beer time scribble and
talk session in Portland. But it looks ok, we got it in Lucid without flames
erupting and it has been verified to fix the issue.

Kees Cook wrote:
> This is a fix for the NX emulation patch to force the brk area well
> outside of the exec randomization area to avoid future allocation or brk
> growth collisions. Normally this isn't a problem, except when the text
> region has been loaded from a PIE binary and the CS limit can't be put
> just above bss.
>
> Additionally, the nx-emulation patch was still randomizing addresses
> even when randomize_va_space was disabled, which would cause collisions
> even faster if someone tried to disable randomization.
>
> BugLink: http://bugs.launchpad.net/bugs/452175
>
> Signed-off-by: Kees Cook <kees.cook at canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
> ---
> arch/x86/kernel/process.c | 12 +++++++++++-
> mm/mmap.c | 11 ++++++++---
> 2 files changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
> index 5284cd2..bf5c156 100644
> --- a/arch/x86/kernel/process.c
> +++ b/arch/x86/kernel/process.c
> @@ -607,6 +607,16 @@ unsigned long arch_align_stack(unsigned long sp)
> unsigned long arch_randomize_brk(struct mm_struct *mm)
> {
> unsigned long range_end = mm->brk + 0x02000000;
> - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
> + unsigned long bump = 0;
> +#ifdef CONFIG_X86_32
> + /* in the case of NX emulation, shove the brk segment way out of the
> + way of the exec randomization area, since it can collide with
> + future allocations if not. */
> + if ( (mm->get_unmapped_exec_area == arch_get_unmapped_exec_area) &&
> + (mm->brk < 0x08000000) ) {
> + bump = (TASK_SIZE/6);
> + }
> +#endif
> + return bump + (randomize_range(mm->brk, range_end, 0) ? : mm->brk);
> }
>
> diff --git a/mm/mmap.c b/mm/mmap.c
> index a1483c5..c6d7e53 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -1500,8 +1500,11 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
> if (flags & MAP_FIXED)
> return addr;
>
> - if (!addr)
> - addr = randomize_range(SHLIB_BASE, 0x01000000, len);
> + if (!addr) {
> + addr = SHLIB_BASE;
> + if ((current->flags & PF_RANDOMIZE) && randomize_va_space)
> + addr = randomize_range(addr, 0x01000000, len);
> + }
>
> if (addr) {
> addr = PAGE_ALIGN(addr);
> @@ -1529,7 +1532,9 @@ arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
> * Up until the brk area we randomize addresses
> * as much as possible:
> */
> - if (addr >= 0x01000000) {
> + if ((current->flags & PF_RANDOMIZE) &&
> + randomize_va_space &&
> + addr >= 0x01000000) {
> tmp = randomize_range(0x01000000,
> PAGE_ALIGN(max(mm->start_brk,
> (unsigned long)0x08000000)), len);


--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team

Kees Cook 01-22-2010 03:47 PM

UBUNTU: SAUCE: x86: brk away from exec rand area
 
Hi Stefan,

On Fri, Jan 22, 2010 at 03:04:16PM +0100, Stefan Bader wrote:
> I d love to understand that foo better, maybe we can do a beer time scribble and
> talk session in Portland. But it looks ok, we got it in Lucid without flames
> erupting and it has been verified to fix the issue.

Yeah, totally. This would be pretty valuable for me too; explaining
memory layouts and this ASLR would kind of help to solidify the ideas
in my head.

-Kees

--
Kees Cook
Ubuntu Security Team

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team


All times are GMT. The time now is 04:16 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.