Re: [RFC PATCH v2 0/2] Randomization of address chosen by mmap.
From: Ilya Smith <hidden>
Date: 2018-03-27 13:51:08
Also in:
linux-alpha, linux-mips, linux-mm, linux-s390, linux-sh, lkml, sparclinux
On 27 Mar 2018, at 10:24, Michal Hocko [off-list ref] wrote: =20 On Mon 26-03-18 22:45:31, Ilya Smith wrote:quoted
=20quoted
On 26 Mar 2018, at 11:46, Michal Hocko [off-list ref] wrote: =20 On Fri 23-03-18 20:55:49, Ilya Smith wrote:quoted
=20quoted
On 23 Mar 2018, at 15:48, Matthew Wilcox [off-list ref] =
wrote:
quoted
quoted
quoted
quoted
=20 On Thu, Mar 22, 2018 at 07:36:36PM +0300, Ilya Smith wrote:quoted
Current implementation doesn't randomize address returned by =
mmap.
quoted
quoted
quoted
quoted
quoted
All the entropy ends with choosing mmap_base_addr at the process creation. After that mmap build very predictable layout of =
address
quoted
quoted
quoted
quoted
quoted
space. It allows to bypass ASLR in many cases. This patch make randomization of address on any mmap call.=20 Why should this be done in the kernel rather than libc? libc is =
perfectly
quoted
quoted
quoted
quoted
capable of specifying random numbers in the first argument of =
mmap.
quoted
quoted
quoted
Well, there is following reasons: 1. It should be done in any libc implementation, what is not =
possible IMO;
quoted
quoted
=20 Is this really so helpful?=20 Yes, ASLR is one of very important mitigation techniques which are =
really used=20
quoted
to protect applications. If there is no ASLR, it is very easy to =
exploit=20
quoted
vulnerable application and compromise the system. We can=E2=80=99t =
just fix all the=20
quoted
vulnerabilities right now, thats why we have mitigations - techniques =
which are=20
quoted
makes exploitation more hard or impossible in some cases. =20 Thats why it is helpful.=20 I am not questioning ASLR in general. I am asking whether we really =
need
per mmap ASLR in general. I can imagine that some environments want to pay the additional price and other side effects, but considering this can be achieved by libc, why to add more code to the kernel?
I believe this is the only one right place for it. Adding these 200+ = lines of=20 code we give this feature for any user - on desktop, on server, on IoT = device,=20 on SCADA, etc. But if only glibc will implement =E2=80=98user-mode-aslr=E2= =80=99 IoT and SCADA=20 devices will never get it.
quoted
quoted
=20quoted
2. User mode is not that layer which should be responsible for =
choosing
quoted
quoted
quoted
random address or handling entropy;=20 Why?=20 Because of the following reasons: 1. To get random address you should have entropy. These entropy =
shouldn=E2=80=99t be=20
quoted
exposed to attacker anyhow, the best case is to get it from kernel. =
So this is
quoted
a syscall.=20 /dev/[u]random is not sufficient?
Using /dev/[u]random makes 3 syscalls - open, read, close. This is a = performance issue.
=20quoted
2. You should have memory map of your process to prevent remapping or =
big
quoted
fragmentation. Kernel already has this map.=20 /proc/self/maps?
Not any system has /proc and parsing /proc/self/maps is robust so it is = the=20 performance issue. libc will have to do it on any mmap. And there is a = possible=20 race here - application may mmap/unmap memory with native syscall during = other=20 thread reading maps.
quoted
You will got another one in libc. And any non-libc user of mmap (via syscall, etc) will make hole in =
your map.
quoted
This one also decrease performance cause you any way call =
syscall_mmap=20
quoted
which will try to find some address for you in worst case, but after =
you already
quoted
did some computing on it.=20 I do not understand. a) you should be prepared to pay an additional price for an additional security measures and b) how would anybody =
punch
a hole into your mapping?=20 =20
I was talking about any code that call mmap directly without libc = wrapper.
quoted
3. The more memory you use in userland for these proposal, the easier =
for
quoted
attacker to leak it or use in exploitation techniques.=20 This is true in general, isn't it? I fail to see how kernel chosen and user chosen ranges would make any difference.
My point here was that libc will have to keep memory representation as a = tree=20 and this tree increase attack surface. It could be hidden in kernel as = it is right now.
=20quoted
4. It is so easy to fix Kernel function and so hard to support memory management from userspace.=20 Well, on the other hand the new layout mode will add a maintenance burden on the kernel and will have to be maintained for ever because =
it
is a user visible ABI.
Thats why I made this patch as RFC and would like to discuss this ABI = here. I=20 made randomize_va_space parameter to allow disable randomisation per = whole=20 system. PF_RANDOMIZE flag may disable randomization for concrete process = (or=20 process groups?). For architecture I=E2=80=99ve made info.random_shift =3D= 0 , so if your=20 arch has small address space you may disable shifting. I also would like = to add=20 some sysctl to allow process/groups to change this value and allow some=20= processes to have shifts bigger then another. Lets discuss it, please.
=20quoted
quoted
quoted
3. Memory fragmentation is unpredictable in this case =20 Off course user mode could use random =E2=80=98hint=E2=80=99 =
address, but kernel may
quoted
quoted
quoted
discard this address if it is occupied for example and allocate =
just before
quoted
quoted
quoted
closest vma. So this solution doesn=E2=80=99t give that much =
security like=20
quoted
quoted
quoted
randomization address inside kernel.=20 The userspace can use the new MAP_FIXED_NOREPLACE to probe for the address range atomically and chose a different range on failure. =20=20 This algorithm should track current memory. If he doesn=E2=80=99t he =
may cause
quoted
infinite loop while trying to choose memory. And each iteration =
increase time
quoted
needed on allocation new memory, what is not preferred by any libc =
library
quoted
developer.=20 Well, I am pretty sure userspace can implement proper free ranges tracking=E2=80=A6
I think we need to know what libc developers will say on implementing = ASLR in=20 user-mode. I am pretty sure they will say =E2=80=98nether=E2=80=99 or = =E2=80=98some-day=E2=80=99. And problem=20 of ASLR will stay forever. Thanks, Ilya