Skip site navigation (1)Skip section navigation (2)
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>
&nbsp;
<p><strong>Van:</strong> Alan Cox &lt;alc@FreeBSD.org&gt;<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: &nbsp;&nbsp;&nbsp;&nbsp;Alan Cox &lt;alc@FreeBSD.org&gt;<br>
AuthorDate: 2023-06-23 17:00:32 +0000<br>
Commit: &nbsp;&nbsp;&nbsp;&nbsp;Alan Cox &lt;alc@FreeBSD.org&gt;<br>
CommitDate: 2023-06-27 04:42:48 +0000<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;vm: Fix anonymous memory clustering under ASLR<br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;By default, our ASLR implementation is supposed to cluster anonymous<br>
&nbsp;&nbsp;&nbsp;&nbsp;memory allocations, unless the application's mmap(..., MAP_ANON, ...)<br>
&nbsp;&nbsp;&nbsp;&nbsp;call included a non-zero address hint. &nbsp;Unfortunately, clustering<br>
&nbsp;&nbsp;&nbsp;&nbsp;never occurred because kern_mmap() always replaced the given address<br>
&nbsp;&nbsp;&nbsp;&nbsp;hint when it was zero. &nbsp;So, the ASLR implementation always believed<br>
&nbsp;&nbsp;&nbsp;&nbsp;that a non-zero hint had been provided and randomized the mapping's<br>
&nbsp;&nbsp;&nbsp;&nbsp;location in the address space. &nbsp;To fix this problem, I'm pushing down<br>
&nbsp;&nbsp;&nbsp;&nbsp;the point at which we convert a hint of zero to the minimum allocatable<br>
&nbsp;&nbsp;&nbsp;&nbsp;address from kern_mmap() to vm_map_find_min().<br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;Reviewed by: &nbsp;&nbsp;&nbsp;kib<br>
&nbsp;&nbsp;&nbsp;&nbsp;MFC after: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2 weeks<br>
&nbsp;&nbsp;&nbsp;&nbsp;Differential Revision: &nbsp;<a href="https://reviews.freebsd.org/D40743">https://reviews.freebsd.org/D40743</a><br>;
---<br>
&nbsp;sys/vm/vm_map.c &nbsp;| 10 +++++++---<br>
&nbsp;sys/vm/vm_map.h &nbsp;| &nbsp;1 +<br>
&nbsp;sys/vm/vm_mmap.c | &nbsp;8 +++++---<br>
&nbsp;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>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Cluster anonymous mappings: 0 = no, 1 = yes if no hint, 2 = always");<br>
&nbsp;<br>
&nbsp;static bool<br>
-clustering_anon_allowed(vm_offset_t addr)<br>
+clustering_anon_allowed(vm_offset_t addr, int cow)<br>
&nbsp;{<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;switch (cluster_anon) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;case 0:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (false);<br>
&nbsp;&nbsp;&nbsp;&nbsp;case 1:<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (addr == 0);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (addr == 0 || (cow &amp; MAP_NO_HINT) != 0);<br>
&nbsp;&nbsp;&nbsp;&nbsp;case 2:<br>
&nbsp;&nbsp;&nbsp;&nbsp;default:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (true);<br>
@@ -2111,7 +2111,7 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,<br>
&nbsp;&nbsp;&nbsp;&nbsp;} else<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alignment = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;en_aslr = (map-&gt;flags &amp; MAP_ASLR) != 0;<br>
- &nbsp;&nbsp;update_anon = cluster = clustering_anon_allowed(*addr) &amp;&amp;<br>
+ &nbsp;&nbsp;update_anon = cluster = clustering_anon_allowed(*addr, cow) &amp;&amp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-&gt;flags &amp; MAP_IS_SUB_MAP) == 0 &amp;&amp; max_addr == 0 &amp;&amp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;find_space != VMFS_NO_SPACE &amp;&amp; object == NULL &amp;&amp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cow &amp; (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>
&nbsp;&nbsp;&nbsp;&nbsp;int rv;<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;hint = *addr;<br>
+ &nbsp;&nbsp;if (hint == 0)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cow |= MAP_NO_HINT;<br>
+ &nbsp;&nbsp;if (hint &lt; min_addr)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*addr = hint = min_addr;<br>
&nbsp;&nbsp;&nbsp;&nbsp;for (;;) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rv = vm_map_find(map, object, offset, addr, length, max_addr,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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>
&nbsp;#define &nbsp;&nbsp;&nbsp;MAP_CREATE_STACK_GAP_DN 0x00020000<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;MAP_VN_EXEC &nbsp;&nbsp;&nbsp;&nbsp;0x00040000<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;MAP_SPLIT_BOUNDARY_MASK 0x00180000<br>
+#define &nbsp;&nbsp;&nbsp;MAP_NO_HINT &nbsp;&nbsp;&nbsp;&nbsp;0x00200000<br>
&nbsp;<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;MAP_SPLIT_BOUNDARY_SHIFT 19<br>
&nbsp;<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>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* the hint would fall in the potential heap space,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* place it after the end of the largest possible heap.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* There should really be a pmap call to determine a reasonable<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* location.<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* For anonymous mappings within the address space of the<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* calling process, the absence of a hint is handled at a<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* lower level in order to implement different clustering<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* strategies for ASLR.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (addr == 0 ||<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (((flags &amp; MAP_ANON) == 0 &amp;&amp; addr == 0) ||<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(addr &gt;= round_page((vm_offset_t)vms-&gt;vm_taddr) &amp;&amp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr &lt; round_page((vm_offset_t)vms-&gt;vm_daddr +<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lim_max(td, RLIMIT_DATA))))<br>
&nbsp;</div>

<hr></div>
</blockquote>
<br>
&nbsp;</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>