summaryrefslogtreecommitdiff
path: root/libexec/ld.elf_so/map_object.c
diff options
context:
space:
mode:
authorthorpej <thorpej@NetBSD.org>2020-03-04 01:21:17 +0000
committerthorpej <thorpej@NetBSD.org>2020-03-04 01:21:17 +0000
commit7b5cd1c22749e34a84fcbc1e5a6dab8d028dfae6 (patch)
treed5c611406ca43d09a5ad8e841091cbe2b94e39d8 /libexec/ld.elf_so/map_object.c
parentbe187b29b9033202a9074911afe582e9dff2de5c (diff)
PT_GNU_RELRO segments are arranged such that their vaddr + memsz ends
on a linker common page size boundary. However, if the common page size used by the linker is less than the VM page size being used by the kernel, this can end up in the middle of a VM page and when the region is write- protected, this can cause objects in neighboring .data to get incorrectly write-protected, resulting in a crash. Avoid this situation by calculating the end of the RELRO region not by rounding memsz up to the VM page size, but rather by adding vaddr + memsz and then truncating to the VM page size. Fixes PR toolchain/55043. XXX pullup-9
Diffstat (limited to 'libexec/ld.elf_so/map_object.c')
-rw-r--r--libexec/ld.elf_so/map_object.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/libexec/ld.elf_so/map_object.c b/libexec/ld.elf_so/map_object.c
index 14afb4a6c92..0416df8c8c9 100644
--- a/libexec/ld.elf_so/map_object.c
+++ b/libexec/ld.elf_so/map_object.c
@@ -1,4 +1,4 @@
-/* $NetBSD: map_object.c,v 1.60 2019/01/06 19:44:54 joerg Exp $ */
+/* $NetBSD: map_object.c,v 1.61 2020/03/04 01:21:17 thorpej Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: map_object.c,v 1.60 2019/01/06 19:44:54 joerg Exp $");
+__RCSID("$NetBSD: map_object.c,v 1.61 2020/03/04 01:21:17 thorpej Exp $");
#endif /* not lint */
#include <errno.h>
@@ -406,8 +406,9 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb)
obj->relocbase = mapbase - base_vaddr;
#ifdef GNU_RELRO
- obj->relro_page = obj->relocbase + round_down(relro_page);
- obj->relro_size = round_up(relro_size);
+ /* rounding happens later. */
+ obj->relro_page = obj->relocbase + relro_page;
+ obj->relro_size = relro_size;
#endif
if (obj->dynamic)