2024-02-17 06:26:09

by Kees Cook

[permalink] [raw]
Subject: [PATCH 0/2] Adjust brk randomness

Hi,

It was recently pointed out[1] that x86_64 brk entropy was not great,
and that on all architectures the brk can (when the random offset is 0)
be immediately adjacent to .bss, leaving no gap that could stop linear
overflows from the .bss. Address both issues.

-Kees

Link: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com [1]

Kees Cook (2):
x86: Increase brk randomness entropy on x86_64
binfmt_elf: Leave a gap between .bss and brk

arch/x86/kernel/process.c | 5 ++++-
fs/binfmt_elf.c | 3 +++
2 files changed, 7 insertions(+), 1 deletion(-)

--
2.34.1



2024-02-17 06:26:12

by Kees Cook

[permalink] [raw]
Subject: [PATCH 1/2] x86: Increase brk randomness entropy on x86_64

In commit c1d171a00294 ("x86: randomize brk"), arch_randomize_brk() was
defined to use a 32MB range (13 bits of entropy), but was never increased
when moving to 64-bit. The default arch_randomize_brk() uses 32MB for
32-bit tasks, and 1GB (18 bits of entropy) for 64-bit tasks. Update
x86_64 to match the entropy used by arm64 and other 64-bit architectures.

Reported-by: [email protected]
Closes: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com/
Signed-off-by: Kees Cook <[email protected]>
---
Cc: Jiri Kosina <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Qi Zheng <[email protected]>
Cc: Alexandre Ghiti <[email protected]>
Cc: [email protected]
---
arch/x86/kernel/process.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ab49ade31b0d..45a9d496fe2a 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -1030,7 +1030,10 @@ unsigned long arch_align_stack(unsigned long sp)

unsigned long arch_randomize_brk(struct mm_struct *mm)
{
- return randomize_page(mm->brk, 0x02000000);
+ if (mmap_is_ia32())
+ return randomize_page(mm->brk, SZ_32M);
+
+ return randomize_page(mm->brk, SZ_1G);
}

/*
--
2.34.1


2024-02-17 06:26:15

by Kees Cook

[permalink] [raw]
Subject: [PATCH 2/2] binfmt_elf: Leave a gap between .bss and brk

Currently the brk starts its randomization immediately after .bss,
which means there is a chance that when the random offset is 0, linear
overflows from .bss can reach into the brk area. Leave at least a single
page gap between .bss and brk (when it has not already been explicitly
relocated into the mmap range).

Reported-by: [email protected]
Closes: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com/
Signed-off-by: Kees Cook <[email protected]>
---
Cc: Jiri Kosina <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Eric Biederman <[email protected]>
Cc: Christophe Leroy <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
fs/binfmt_elf.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 5397b552fbeb..7862962f7a85 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1262,6 +1262,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) &&
elf_ex->e_type == ET_DYN && !interpreter) {
mm->brk = mm->start_brk = ELF_ET_DYN_BASE;
+ } else {
+ /* Otherwise leave a gap between .bss and brk. */
+ mm->brk = mm->start_brk = mm->brk + PAGE_SIZE;
}

mm->brk = mm->start_brk = arch_randomize_brk(mm);
--
2.34.1


2024-02-18 00:27:33

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 0/2] Adjust brk randomness

On February 16, 2024 10:25:42 PM PST, Kees Cook <[email protected]> wrote:
>Hi,
>
>It was recently pointed out[1] that x86_64 brk entropy was not great,
>and that on all architectures the brk can (when the random offset is 0)
>be immediately adjacent to .bss, leaving no gap that could stop linear
>overflows from the .bss. Address both issues.
>
>-Kees
>
>Link: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com [1]
>
>Kees Cook (2):
> x86: Increase brk randomness entropy on x86_64
> binfmt_elf: Leave a gap between .bss and brk
>
> arch/x86/kernel/process.c | 5 ++++-
> fs/binfmt_elf.c | 3 +++
> 2 files changed, 7 insertions(+), 1 deletion(-)
>

Why do we even have the brk, or perhaps more importantly, why do we use it? Is there any reason whatsoever why glibc uses brk instead of mmap to her heap memory?

I thought the base of the brk wasn't even known to userspace other than in the form of the image end...

2024-02-18 01:25:48

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH 0/2] Adjust brk randomness

On Sat, Feb 17, 2024 at 04:25:33PM -0800, H. Peter Anvin wrote:
> On February 16, 2024 10:25:42 PM PST, Kees Cook <[email protected]> wrote:
> >Hi,
> >
> >It was recently pointed out[1] that x86_64 brk entropy was not great,
> >and that on all architectures the brk can (when the random offset is 0)
> >be immediately adjacent to .bss, leaving no gap that could stop linear
> >overflows from the .bss. Address both issues.
> >
> >-Kees
> >
> >Link: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com [1]
> >
> >Kees Cook (2):
> > x86: Increase brk randomness entropy on x86_64
> > binfmt_elf: Leave a gap between .bss and brk
> >
> > arch/x86/kernel/process.c | 5 ++++-
> > fs/binfmt_elf.c | 3 +++
> > 2 files changed, 7 insertions(+), 1 deletion(-)
> >
>
> Why do we even have the brk, or perhaps more importantly, why do we use it? Is there any reason whatsoever why glibc uses brk instead of mmap to her heap memory?
>
> I thought the base of the brk wasn't even known to userspace other than in the form of the image end...

AFAIK, it's part of ELF ABI, and the loader uses it only for very early
allocations. e.g. it's what shows up as "[heap]" in /proc/$pid/maps.
It's also available to any program that wants it still (see "man brk").
I don't think glibc has plans to redirect it.

--
Kees Cook

2024-02-26 10:51:25

by Jiri Kosina

[permalink] [raw]
Subject: Re: [PATCH 1/2] x86: Increase brk randomness entropy on x86_64

On Fri, 16 Feb 2024, Kees Cook wrote:

> In commit c1d171a00294 ("x86: randomize brk"), arch_randomize_brk() was
> defined to use a 32MB range (13 bits of entropy), but was never increased
> when moving to 64-bit. The default arch_randomize_brk() uses 32MB for
> 32-bit tasks, and 1GB (18 bits of entropy) for 64-bit tasks. Update
> x86_64 to match the entropy used by arm64 and other 64-bit architectures.
>
> Reported-by: [email protected]
> Closes: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com/
> Signed-off-by: Kees Cook <[email protected]>

Wow, this is a pretty aged code indeed.

Acked-by: Jiri Kosina <[email protected]>

Thanks,

--
Jiri Kosina
SUSE Labs


Subject: [tip: x86/core] x86: Increase brk randomness entropy for 64-bit systems

The following commit has been merged into the x86/core branch of tip:

Commit-ID: 44c76825d6eefee9eb7ce06c38e1a6632ac7eb7d
Gitweb: https://git.kernel.org/tip/44c76825d6eefee9eb7ce06c38e1a6632ac7eb7d
Author: Kees Cook <[email protected]>
AuthorDate: Fri, 16 Feb 2024 22:25:43 -08:00
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Tue, 27 Feb 2024 00:23:55 +01:00

x86: Increase brk randomness entropy for 64-bit systems

In commit c1d171a00294 ("x86: randomize brk"), arch_randomize_brk() was
defined to use a 32MB range (13 bits of entropy), but was never increased
when moving to 64-bit. The default arch_randomize_brk() uses 32MB for
32-bit tasks, and 1GB (18 bits of entropy) for 64-bit tasks.

Update x86_64 to match the entropy used by arm64 and other 64-bit
architectures.

Reported-by: [email protected]
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Jiri Kosina <[email protected]>
Closes: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com/
Link: https://lore.kernel.org/r/[email protected]
---
arch/x86/kernel/process.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ab49ade..45a9d49 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -1030,7 +1030,10 @@ unsigned long arch_align_stack(unsigned long sp)

unsigned long arch_randomize_brk(struct mm_struct *mm)
{
- return randomize_page(mm->brk, 0x02000000);
+ if (mmap_is_ia32())
+ return randomize_page(mm->brk, SZ_32M);
+
+ return randomize_page(mm->brk, SZ_1G);
}

/*

2024-04-24 19:21:50

by Kees Cook

[permalink] [raw]
Subject: Re: (subset) [PATCH 2/2] binfmt_elf: Leave a gap between .bss and brk

On Fri, 16 Feb 2024 22:25:44 -0800, Kees Cook wrote:
> Currently the brk starts its randomization immediately after .bss,
> which means there is a chance that when the random offset is 0, linear
> overflows from .bss can reach into the brk area. Leave at least a single
> page gap between .bss and brk (when it has not already been explicitly
> relocated into the mmap range).
>
>
> [...]

Patch 1/2 was already applied via x86 tip, so I'll grab this one for the execve/binfmt tree.

Applied to for-next/execve.

[2/2] binfmt_elf: Leave a gap between .bss and brk
https://git.kernel.org/kees/c/2a5eb9995528

Take care,

--
Kees Cook