[PATCH v2 03/10] loader: Generalise is_addr_reserved to find overlapping address ranges.

Jinoh Kang wine at gitlab.winehq.org
Thu Apr 28 13:02:53 CDT 2022


From: Jinoh Kang <jinoh.kang.kr at gmail.com>

Rename is_addr_reserved to find_preload_reserved_area, with the
following changes:

- Accept second argument "size" which specifies the size of the address
  range to test.
- Return the index of the matching entry, or -1 if none found.

Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
 loader/preloader.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/loader/preloader.c b/loader/preloader.c
index 13406984c99..7584de51eca 100644
--- a/loader/preloader.c
+++ b/loader/preloader.c
@@ -1503,18 +1503,29 @@ error:
     fatal_error( "invalid WINEPRELOADRESERVE value '%s'\n", str );
 }
 
-/* check if address is in one of the reserved ranges */
-static int is_addr_reserved( const void *addr )
+/*
+ * find_preload_reserved_area
+ *
+ * Check if the given address range overlaps with one of the reserved ranges.
+ */
+static int find_preload_reserved_area( const void *addr, size_t size )
 {
+    /* Make the interval inclusive to avoid integer overflow. */
+    unsigned long start = (unsigned long)addr;
+    unsigned long end = (unsigned long)addr + size - 1;
     int i;
 
+    /* Handle size == 0 specifically since "end" may overflow otherwise. */
+    if (!size)
+        return -1;
+
     for (i = 0; preload_info[i].size; i++)
     {
-        if ((const char *)addr >= (const char *)preload_info[i].addr &&
-            (const char *)addr <  (const char *)preload_info[i].addr + preload_info[i].size)
-            return 1;
+        if (end   >= (unsigned long)preload_info[i].addr &&
+            start <= (unsigned long)preload_info[i].addr + preload_info[i].size - 1)
+            return i;
     }
-    return 0;
+    return -1;
 }
 
 /* remove a range from the preload list */
@@ -1537,7 +1548,7 @@ static int is_in_preload_range( const struct wld_auxv *av, int type )
 {
     while (av->a_type != AT_NULL)
     {
-        if (av->a_type == type) return is_addr_reserved( (const void *)av->a_un.a_val );
+        if (av->a_type == type) return find_preload_reserved_area( (const void *)av->a_un.a_val, 1 ) >= 0;
         av++;
     }
     return 0;
@@ -1625,7 +1636,7 @@ void* wld_start( void **stack )
 
     /* add an executable page at the top of the address space to defeat
      * broken no-exec protections that play with the code selector limit */
-    if (is_addr_reserved( (char *)0x80000000 - page_size ))
+    if (find_preload_reserved_area( (char *)0x80000000 - page_size, page_size ) >= 0)
         wld_mprotect( (char *)0x80000000 - page_size, page_size, PROT_EXEC | PROT_READ );
 
     /* load the main binary */
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/6



More information about the wine-devel mailing list