[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 22/43: libshouldbeinlibc: Fix wiring code.
From: |
Samuel Thibault |
Subject: |
[hurd] 22/43: libshouldbeinlibc: Fix wiring code. |
Date: |
Mon, 11 Sep 2017 07:10:10 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch upstream
in repository hurd.
commit 01ced1f5856659f4f457f39c270dd10f64ccaab8
Author: Justus Winter <address@hidden>
Date: Fri Aug 11 18:10:15 2017 +0200
libshouldbeinlibc: Fix wiring code.
* libshouldbeinlibc/wire.c (statically_linked): New function.
(loaded): Remove check.
(wire_segment_internal): Fix error handling. Be smarter about the
wiring, inspired by the mach-defpager code.
(wire_segment): Fix error handling.
(wire_task_self): Fix error handling. Distinguish between static
binaries and dynamic binaries without DT_DEBUG or link map. When we
don't have a map, fall back to wiring the whole space. Wire future
allocations.
* libshouldbeinlibc/wire.h (wire_task_self): Return error_t.
(wire_segment): Likewise.
---
libshouldbeinlibc/wire.c | 144 +++++++++++++++++++++++++++++++----------------
libshouldbeinlibc/wire.h | 4 +-
2 files changed, 97 insertions(+), 51 deletions(-)
diff --git a/libshouldbeinlibc/wire.c b/libshouldbeinlibc/wire.c
index ca5d32b..5b41555 100644
--- a/libshouldbeinlibc/wire.c
+++ b/libshouldbeinlibc/wire.c
@@ -24,6 +24,7 @@
#include <hurd.h>
#include <error.h>
#include <elf.h>
+#include <mach/gnumach.h>
#pragma weak _DYNAMIC
#pragma weak dlopen
@@ -34,15 +35,18 @@
#define RTLD_NOLOAD 0
#endif
+static int
+statically_linked (void)
+{
+ return &_DYNAMIC == 0; /* statically linked */
+}
+
/* Find the list of shared objects */
static struct link_map *
loaded (void)
{
ElfW(Dyn) *d;
- if (&_DYNAMIC == 0) /* statically linked */
- return 0;
-
for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d)
if (d->d_tag == DT_DEBUG)
{
@@ -79,7 +83,7 @@ map_extent (struct link_map *map)
/* Wire down all memory currently allocated at START for LEN bytes;
host_priv is the privileged host port. */
-static void
+static error_t
wire_segment_internal (vm_address_t start,
vm_size_t len,
host_priv_t host_priv)
@@ -101,40 +105,63 @@ wire_segment_internal (vm_address_t start,
err = vm_region (mach_task_self (), &addr, &size, &protection,
&max_protection, &inheritance, &shared, &object_name,
&offset);
+ if (err == KERN_NO_SPACE)
+ return 0; /* We're done. */
if (err)
- return;
-
- /* The current region begins at ADDR and is SIZE long. If it
- extends beyond the LEN, prune it. */
- if (addr + size > start + len)
- size = len - (addr - start);
-
- /* Set protection to allow all access possible */
- vm_protect (mach_task_self (), addr, size, 0, max_protection);
-
- /* Generate write faults */
- for (poke = (char *) addr;
- (vm_address_t) poke < addr + size;
- poke += vm_page_size)
- *poke = *poke;
-
- /* Wire pages */
- vm_wire (host_priv, mach_task_self (), addr, size, max_protection);
-
- /* Set protection back to what it was */
- vm_protect (mach_task_self (), addr, size, 0, protection);
-
-
+ return err;
mach_port_deallocate (mach_task_self (), object_name);
+ if (protection != VM_PROT_NONE)
+ {
+ /* The VM system cannot cope with a COW fault on another
+ unrelated virtual copy happening later when we have
+ wired down the original page. So we must touch all our
+ pages before wiring to make sure that only we will ever
+ use them. */
+
+ /* The current region begins at ADDR and is SIZE long. If it
+ extends beyond the LEN, prune it. */
+ if (addr + size > start + len)
+ size = len - (addr - start);
+
+ /* Set protection to allow all access possible */
+ if (!(protection & VM_PROT_WRITE))
+ {
+ err = vm_protect (mach_task_self (), addr, size, 0,
max_protection);
+ if (err)
+ return err;
+ }
+
+ /* Generate write faults */
+ for (poke = (char *) addr;
+ (vm_address_t) poke < addr + size;
+ poke += vm_page_size)
+ *poke = *poke;
+
+ /* Wire pages */
+ err = vm_wire (host_priv, mach_task_self (), addr, size, protection);
+ if (err)
+ return err;
+
+ /* Set protection back to what it was */
+ if (!(protection & VM_PROT_WRITE))
+ {
+ err = vm_protect (mach_task_self (), addr, size, 0, protection);
+ if (err)
+ return err;
+ }
+ }
+
len -= (addr - start) + size;
start = addr + size;
}
while (len);
+
+ return err;
}
/* Wire down all memory currently allocated at START for LEN bytes. */
-void
+error_t
wire_segment (vm_address_t start,
vm_size_t len)
{
@@ -142,45 +169,64 @@ wire_segment (vm_address_t start,
error_t err;
err = get_privileged_ports (&host, &device);
- if (!err)
- {
- wire_segment_internal (start, len, host);
- mach_port_deallocate (mach_task_self (), host);
- mach_port_deallocate (mach_task_self (), device);
- }
-}
+ if (err)
+ return err;
+ err = wire_segment_internal (start, len, host);
+ mach_port_deallocate (mach_task_self (), host);
+ mach_port_deallocate (mach_task_self (), device);
+ return err;
+}
/* Wire down all the text and data (including from shared libraries)
for the current program. */
-void
+error_t
wire_task_self ()
{
- struct link_map *map;
mach_port_t host, device;
error_t err;
- extern char _edata, _etext, __data_start;
err = get_privileged_ports (&host, &device);
if (err)
- return;
+ return err;
- map = loaded ();
- if (!map)
+ if (statically_linked ())
{
extern void _start ();
+ extern char _edata, _etext, __data_start;
vm_address_t text_start = (vm_address_t) &_start;
- wire_segment_internal (text_start,
- (vm_size_t) (&_etext - text_start),
- host);
- wire_segment_internal ((vm_address_t) &__data_start,
- (vm_size_t) (&_edata - &__data_start),
- host);
+ err = wire_segment_internal (text_start,
+ (vm_size_t) (&_etext - text_start),
+ host);
+ if (err)
+ goto out;
+
+ err = wire_segment_internal ((vm_address_t) &__data_start,
+ (vm_size_t) (&_edata - &__data_start),
+ host);
}
else
- while (map)
- wire_segment ((vm_address_t) map->l_addr, map_extent (map));
+ {
+ struct link_map *map;
+
+ map = loaded ();
+ if (map)
+ for (err = 0; ! err && map; map = map->l_next)
+ err = wire_segment_internal ((vm_address_t) map->l_addr,
+ map_extent (map), host);
+ else
+ err = wire_segment_internal (VM_MIN_ADDRESS, VM_MAX_ADDRESS, host);
+ }
+
+ if (err)
+ goto out;
+
+ /* Automatically wire down future mappings, including those that are
+ currently PROT_NONE but become accessible. */
+ err = vm_wire_all (host, mach_task_self (), VM_WIRE_ALL);
+ out:
mach_port_deallocate (mach_task_self (), host);
mach_port_deallocate (mach_task_self (), device);
+ return err;
}
diff --git a/libshouldbeinlibc/wire.h b/libshouldbeinlibc/wire.h
index 6783cc5..2f310cf 100644
--- a/libshouldbeinlibc/wire.h
+++ b/libshouldbeinlibc/wire.h
@@ -20,7 +20,7 @@
/* Wire down all the text and data (including from shared libraries)
for the current program. */
-void wire_task_self (void);
+error_t wire_task_self (void);
/* Wire down all memory currently allocated at START for LEN bytes. */
-void wire_segment (vm_address_t start, vm_size_t len);
+error_t wire_segment (vm_address_t start, vm_size_t len);
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git
- [hurd] 04/43: hurd: Fix the use of polymorphic types., (continued)
- [hurd] 04/43: hurd: Fix the use of polymorphic types., Samuel Thibault, 2017/09/11
- [hurd] 07/43: Fix taking into account prefix for xkb-data installation, Samuel Thibault, 2017/09/11
- [hurd] 06/43: trans: Fix parallel build race around MIG-generated headers, Samuel Thibault, 2017/09/11
- [hurd] 09/43: libshouldbeinlibc: Add missing include., Samuel Thibault, 2017/09/11
- [hurd] 05/43: ext2fs: Reduce verbosity of missing xattr support on the FS, Samuel Thibault, 2017/09/11
- [hurd] 11/43: build: Drop unused/unsubstituted config variables, Samuel Thibault, 2017/09/11
- [hurd] 10/43: Revert "Fix taking into account prefix for xkb-data installation", Samuel Thibault, 2017/09/11
- [hurd] 19/43: libdiskfs: Make mapping the time device more robust., Samuel Thibault, 2017/09/11
- [hurd] 01/43: procfs: Remove superfluous calls., Samuel Thibault, 2017/09/11
- [hurd] 13/43: Fix harmless indentation errors tripping [-Wmisleading-indentation]., Samuel Thibault, 2017/09/11
- [hurd] 22/43: libshouldbeinlibc: Fix wiring code.,
Samuel Thibault <=
- [hurd] 27/43: eth-multiplexer: Generalize function and improve error handling., Samuel Thibault, 2017/09/11
- [hurd] 32/43: eth-multiplexer: Fix type check., Samuel Thibault, 2017/09/11
- [hurd] 38/43: trans/mtab: Fix warnings., Samuel Thibault, 2017/09/11
- [hurd] 41/43: exec: Avoid calling mmap with zero size, Samuel Thibault, 2017/09/11
- [hurd] 24/43: eth-multiplexer: Fix error handling., Samuel Thibault, 2017/09/11
- [hurd] 12/43: Fix typo., Samuel Thibault, 2017/09/11
- [hurd] 21/43: startup: Fix retrieving the privileged ports., Samuel Thibault, 2017/09/11
- [hurd] 25/43: eth-multiplexer: Implement getting the devices flags., Samuel Thibault, 2017/09/11
- [hurd] 20/43: ext2fs: Fix warning., Samuel Thibault, 2017/09/11
- [hurd] 18/43: Make build system more robust., Samuel Thibault, 2017/09/11