Re: git: d8e6f4946cec - main - vm: Fix anonymous memory clustering under ASLR
- In reply to: Alan Cox : "git: d8e6f4946cec - main - vm: Fix anonymous memory clustering under ASLR"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 27 Jun 2023 11:56:48 UTC
Hi,
Could this be a reason of this issue?
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=260187
Regards,
Ronald.
Van: Alan Cox <alc@FreeBSD.org>
Datum: dinsdag, 27 juni 2023 06:43
Aan: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Onderwerp: git: d8e6f4946cec - main - vm: Fix anonymous memory clustering under ASLR
>
> The branch main has been updated by alc:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=d8e6f4946cec0b84a6997d62e791b8cf993741b2
>
> commit d8e6f4946cec0b84a6997d62e791b8cf993741b2
> Author: Alan Cox <alc@FreeBSD.org>
> AuthorDate: 2023-06-23 17:00:32 +0000
> Commit: Alan Cox <alc@FreeBSD.org>
> CommitDate: 2023-06-27 04:42:48 +0000
>
> vm: Fix anonymous memory clustering under ASLR
>
> By default, our ASLR implementation is supposed to cluster anonymous
> memory allocations, unless the application's mmap(..., MAP_ANON, ...)
> call included a non-zero address hint. Unfortunately, clustering
> never occurred because kern_mmap() always replaced the given address
> hint when it was zero. So, the ASLR implementation always believed
> that a non-zero hint had been provided and randomized the mapping's
> location in the address space. To fix this problem, I'm pushing down
> the point at which we convert a hint of zero to the minimum allocatable
> address from kern_mmap() to vm_map_find_min().
>
> Reviewed by: kib
> MFC after: 2 weeks
> Differential Revision: https://reviews.freebsd.org/D40743
> ---
> sys/vm/vm_map.c | 10 +++++++---
> sys/vm/vm_map.h | 1 +
> sys/vm/vm_mmap.c | 8 +++++---
> 3 files changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
> index f5863a9b9939..a02107b5e64d 100644
> --- a/sys/vm/vm_map.c
> +++ b/sys/vm/vm_map.c
> @@ -1981,14 +1981,14 @@ SYSCTL_INT(_vm, OID_AUTO, cluster_anon, CTLFLAG_RW,
> "Cluster anonymous mappings: 0 = no, 1 = yes if no hint, 2 = always");
>
> static bool
> -clustering_anon_allowed(vm_offset_t addr)
> +clustering_anon_allowed(vm_offset_t addr, int cow)
> {
>
> switch (cluster_anon) {
> case 0:
> return (false);
> case 1:
> - return (addr == 0);
> + return (addr == 0 || (cow & MAP_NO_HINT) != 0);
> case 2:
> default:
> return (true);
> @@ -2111,7 +2111,7 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
> } else
> alignment = 0;
> en_aslr = (map->flags & MAP_ASLR) != 0;
> - update_anon = cluster = clustering_anon_allowed(*addr) &&
> + update_anon = cluster = clustering_anon_allowed(*addr, cow) &&
> (map->flags & MAP_IS_SUB_MAP) == 0 && max_addr == 0 &&
> find_space != VMFS_NO_SPACE && object == NULL &&
> (cow & (MAP_INHERIT_SHARE | MAP_STACK_GROWS_UP |
> @@ -2255,6 +2255,10 @@ vm_map_find_min(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
> int rv;
>
> hint = *addr;
> + if (hint == 0)
> + cow |= MAP_NO_HINT;
> + if (hint < min_addr)
> + *addr = hint = min_addr;
> for (;;) {
> rv = vm_map_find(map, object, offset, addr, length, max_addr,
> find_space, prot, max, cow);
> diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
> index 2ac54a39a57b..fd8b606e8ddc 100644
> --- a/sys/vm/vm_map.h
> +++ b/sys/vm/vm_map.h
> @@ -383,6 +383,7 @@ long vmspace_resident_count(struct vmspace *vmspace);
> #define MAP_CREATE_STACK_GAP_DN 0x00020000
> #define MAP_VN_EXEC 0x00040000
> #define MAP_SPLIT_BOUNDARY_MASK 0x00180000
> +#define MAP_NO_HINT 0x00200000
>
> #define MAP_SPLIT_BOUNDARY_SHIFT 19
>
> diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
> index 56345fcaf560..408e077476dd 100644
> --- a/sys/vm/vm_mmap.c
> +++ b/sys/vm/vm_mmap.c
> @@ -353,10 +353,12 @@ kern_mmap(struct thread *td, const struct mmap_req *mrp)
> * the hint would fall in the potential heap space,
> * place it after the end of the largest possible heap.
> *
> - * There should really be a pmap call to determine a reasonable
> - * location.
> + * For anonymous mappings within the address space of the
> + * calling process, the absence of a hint is handled at a
> + * lower level in order to implement different clustering
> + * strategies for ASLR.
> */
> - if (addr == 0 ||
> + if (((flags & MAP_ANON) == 0 && addr == 0) ||
> (addr >= round_page((vm_offset_t)vms->vm_taddr) &&
> addr < round_page((vm_offset_t)vms->vm_daddr +
> lim_max(td, RLIMIT_DATA))))
>
>
>
>