Date: Tue, 27 Jun 2023 13:56:48 +0200 (CEST) From: Ronald Klop <ronald-lists@klop.ws> To: Alan Cox <alc@FreeBSD.org> Cc: dev-commits-src-all@FreeBSD.org, src-committers@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: Re: git: d8e6f4946cec - main - vm: Fix anonymous memory clustering under ASLR Message-ID: <1976086601.6443.1687867008855@localhost> In-Reply-To: <202306270443.35R4hofY050812@gitrepo.freebsd.org> References: <202306270443.35R4hofY050812@gitrepo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
------=_Part_6442_948850698.1687867008768 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit 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)))) > > > > ------=_Part_6442_948850698.1687867008768 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit <html><head></head><body>Hi,<br> <br> Could this be a reason of this issue?<br> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=260187<br> <br> Regards,<br> Ronald.<br> <br> <p><strong>Van:</strong> Alan Cox <alc@FreeBSD.org><br> <strong>Datum:</strong> dinsdag, 27 juni 2023 06:43<br> <strong>Aan:</strong> src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org<br> <strong>Onderwerp:</strong> git: d8e6f4946cec - main - vm: Fix anonymous memory clustering under ASLR</p> <blockquote style="padding-right: 0px; padding-left: 5px; margin-left: 5px; border-left: #000000 2px solid; margin-right: 0px"> <div class="MessageRFC822Viewer" id="P"> <div class="TextPlainViewer" id="P.P">The branch main has been updated by alc:<br> <br> URL: <a href="https://cgit.FreeBSD.org/src/commit/?id=d8e6f4946cec0b84a6997d62e791b8cf993741b2">https://cgit.FreeBSD.org/src/commit/?id=d8e6f4946cec0b84a6997d62e791b8cf993741b2</a><br> <br> commit d8e6f4946cec0b84a6997d62e791b8cf993741b2<br> Author: Alan Cox <alc@FreeBSD.org><br> AuthorDate: 2023-06-23 17:00:32 +0000<br> Commit: Alan Cox <alc@FreeBSD.org><br> CommitDate: 2023-06-27 04:42:48 +0000<br> <br> vm: Fix anonymous memory clustering under ASLR<br> <br> By default, our ASLR implementation is supposed to cluster anonymous<br> memory allocations, unless the application's mmap(..., MAP_ANON, ...)<br> call included a non-zero address hint. Unfortunately, clustering<br> never occurred because kern_mmap() always replaced the given address<br> hint when it was zero. So, the ASLR implementation always believed<br> that a non-zero hint had been provided and randomized the mapping's<br> location in the address space. To fix this problem, I'm pushing down<br> the point at which we convert a hint of zero to the minimum allocatable<br> address from kern_mmap() to vm_map_find_min().<br> <br> Reviewed by: kib<br> MFC after: 2 weeks<br> Differential Revision: <a href="https://reviews.freebsd.org/D40743">https://reviews.freebsd.org/D40743</a><br> ---<br> sys/vm/vm_map.c | 10 +++++++---<br> sys/vm/vm_map.h | 1 +<br> sys/vm/vm_mmap.c | 8 +++++---<br> 3 files changed, 13 insertions(+), 6 deletions(-)<br> <br> diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c<br> index f5863a9b9939..a02107b5e64d 100644<br> --- a/sys/vm/vm_map.c<br> +++ b/sys/vm/vm_map.c<br> @@ -1981,14 +1981,14 @@ SYSCTL_INT(_vm, OID_AUTO, cluster_anon, CTLFLAG_RW,<br> "Cluster anonymous mappings: 0 = no, 1 = yes if no hint, 2 = always");<br> <br> static bool<br> -clustering_anon_allowed(vm_offset_t addr)<br> +clustering_anon_allowed(vm_offset_t addr, int cow)<br> {<br> <br> switch (cluster_anon) {<br> case 0:<br> return (false);<br> case 1:<br> - return (addr == 0);<br> + return (addr == 0 || (cow & MAP_NO_HINT) != 0);<br> case 2:<br> default:<br> return (true);<br> @@ -2111,7 +2111,7 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,<br> } else<br> alignment = 0;<br> en_aslr = (map->flags & MAP_ASLR) != 0;<br> - update_anon = cluster = clustering_anon_allowed(*addr) &&<br> + update_anon = cluster = clustering_anon_allowed(*addr, cow) &&<br> (map->flags & MAP_IS_SUB_MAP) == 0 && max_addr == 0 &&<br> find_space != VMFS_NO_SPACE && object == NULL &&<br> (cow & (MAP_INHERIT_SHARE | MAP_STACK_GROWS_UP |<br> @@ -2255,6 +2255,10 @@ vm_map_find_min(vm_map_t map, vm_object_t object, vm_ooffset_t offset,<br> int rv;<br> <br> hint = *addr;<br> + if (hint == 0)<br> + cow |= MAP_NO_HINT;<br> + if (hint < min_addr)<br> + *addr = hint = min_addr;<br> for (;;) {<br> rv = vm_map_find(map, object, offset, addr, length, max_addr,<br> find_space, prot, max, cow);<br> diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h<br> index 2ac54a39a57b..fd8b606e8ddc 100644<br> --- a/sys/vm/vm_map.h<br> +++ b/sys/vm/vm_map.h<br> @@ -383,6 +383,7 @@ long vmspace_resident_count(struct vmspace *vmspace);<br> #define MAP_CREATE_STACK_GAP_DN 0x00020000<br> #define MAP_VN_EXEC 0x00040000<br> #define MAP_SPLIT_BOUNDARY_MASK 0x00180000<br> +#define MAP_NO_HINT 0x00200000<br> <br> #define MAP_SPLIT_BOUNDARY_SHIFT 19<br> <br> diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c<br> index 56345fcaf560..408e077476dd 100644<br> --- a/sys/vm/vm_mmap.c<br> +++ b/sys/vm/vm_mmap.c<br> @@ -353,10 +353,12 @@ kern_mmap(struct thread *td, const struct mmap_req *mrp)<br> * the hint would fall in the potential heap space,<br> * place it after the end of the largest possible heap.<br> *<br> - * There should really be a pmap call to determine a reasonable<br> - * location.<br> + * For anonymous mappings within the address space of the<br> + * calling process, the absence of a hint is handled at a<br> + * lower level in order to implement different clustering<br> + * strategies for ASLR.<br> */<br> - if (addr == 0 ||<br> + if (((flags & MAP_ANON) == 0 && addr == 0) ||<br> (addr >= round_page((vm_offset_t)vms->vm_taddr) &&<br> addr < round_page((vm_offset_t)vms->vm_daddr +<br> lim_max(td, RLIMIT_DATA))))<br> </div> <hr></div> </blockquote> <br> </body></html> ------=_Part_6442_948850698.1687867008768--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1976086601.6443.1687867008855>