[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <202407300858.EC28E15@keescook>
Date: Tue, 30 Jul 2024 09:17:13 -0700
From: Kees Cook <kees@...nel.org>
To: "Prithivi Raj.S" <prithivi.s017@...il.com>
Cc: linux-hardening@...r.kernel.org
Subject: Re: Unexpected Heap Randomization Behavior in Kernel Version 5.10.216
On Tue, Jul 30, 2024 at 04:45:29PM +0530, Prithivi Raj.S wrote:
> I have been testing Address Space Layout Randomization (ASLR)
> functionalities with the kernel.randomize_va_space sysctl parameter.
> According to the kernel documentation:
>
> 0 disables randomization.
> 1 randomizes the address of mmap base, stack, and VDSO page.
> 2 randomizes the heap address.
>
> However, I have observed that in kernel version 5.10.216, the heap
> base address is being randomized even when kernel.randomize_va_space
> is set to 1. This behavior is not the same as described for this
> parameter.
>
> I tested this on an older kernel version (3.10.0) from the CentOS 7.9
> distribution, where the feature worked as documented.
>
> Test Code:
>
> int main() {
> // Get the current end of the heap
> void *heap_addr = sbrk(0);
>
> printf("Current end of heap (base address): %p\n", heap_addr);
>
> return 0;
> }
>
> I would like to know if this behavior indicates a kernel bug or if the
> heap address randomization is being influenced by other factors. This
> is my first communication with the Linux community, so please let me
> know if there is anything inappropriate or missing in my report. I am
> happy to provide any additional information if needed.
Ignoring randomize_va_space=2 is not intended, but I suspect it may be
related to PIE randomization (text base randomization), as the brk area
is in a fixed position relative to the text address when not separately
randomized, but this has the appearance of a random brk address (which
is really showing the text address randomization).
What was your base OS for the v5.10 test? I know at least Ubuntu does
PIE builds (-pie -fPIE) by default in their compiler, and other distros
are finally starting to catch up to them.
Try this:
int main() {
// Get the current end of the heap
void *heap_addr = sbrk(0);
void *main_addr = main;
printf("main: %p\n", main_addr);
printf("brk: %p\n", heap_addr);
printf("main/brk offset: %lu\n",
(unsigned long)heap_addr -
(unsigned long)main_addr);
return 0;
}
Here's what I see:
# sysctl -w kernel/randomize_va_space=2
kernel.randomize_va_space = 2
# ./test
main: 0x5efc40341169
brk: 0x5efc41999000
main/brk offset: 23428759
# ./test
main: 0x5bd8d1283169
brk: 0x5bd8d2cd8000
main/brk offset: 27610775
# sysctl -w kernel/randomize_va_space=1
kernel.randomize_va_space = 1
# ./test
main: 0x64452def3169
brk: 0x64452def7000
main/brk offset: 16023
# ./test
main: 0x5dc1e726d169
brk: 0x5dc1e7271000
main/brk offset: 16023
With randomize_va_space=2, the first 2 runs of "test" show differing
"main" addresses, and differing main/brk offsets.
With randomize_va_space=1, the next 2 runs of "test" still show the
randomized "main" address, but unchanged main/brk offsets. (But the
literal brk address is different between the two runs.)
To turn off PIE builds, use "-no-pie":
# gcc test.c -no-pie -o test
# sysctl -w kernel/randomize_va_space=2
kernel.randomize_va_space = 2
# ./test
main: 0x401156
brk: 0x1cb6000
main/brk offset: 25906858
# ./test
main: 0x401156
brk: 0xe1f000
main/brk offset: 10608298
# sysctl -w kernel/randomize_va_space=1
kernel.randomize_va_space = 1
# ./test
main: 0x401156
brk: 0x405000
main/brk offset: 16042
# ./test
main: 0x401156
brk: 0x405000
main/brk offset: 16042
Without text randomization, under randomize_va_space=2, the brk
offset (and address) are randomized. And under randomize_va_space=1,
the brk offset (and the resulting address) are NOT randomized.
Perhaps the docs for randomize_va_space need some clarification... :)
-Kees
--
Kees Cook
Powered by blists - more mailing lists