From 61268f23daa4c166e574eb33f00d1ddebf981f91 Mon Sep 17 00:00:00 2001 From: christos Date: Sun, 30 Dec 2018 01:48:37 +0000 Subject: [PATCH] binutils 2.31.1 can put copy relocations in the relro segment. Delay protecting the relro segment for the main object until copy relocations are done. --- libexec/ld.elf_so/reloc.c | 22 +++++++++------------- libexec/ld.elf_so/rtld.c | 23 +++++++++++++++++++++-- libexec/ld.elf_so/rtld.h | 4 +++- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/libexec/ld.elf_so/reloc.c b/libexec/ld.elf_so/reloc.c index 425fc0c259e6..4b9ba49ef264 100644 --- a/libexec/ld.elf_so/reloc.c +++ b/libexec/ld.elf_so/reloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: reloc.c,v 1.113 2018/10/17 23:36:58 joerg Exp $ */ +/* $NetBSD: reloc.c,v 1.114 2018/12/30 01:48:37 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -39,7 +39,7 @@ #include #ifndef lint -__RCSID("$NetBSD: reloc.c,v 1.113 2018/10/17 23:36:58 joerg Exp $"); +__RCSID("$NetBSD: reloc.c,v 1.114 2018/12/30 01:48:37 christos Exp $"); #endif /* not lint */ #include @@ -102,10 +102,10 @@ _rtld_do_copy_relocation(const Obj_Entry *dstobj, const Elf_Rela *rela) return (-1); } srcaddr = (const void *)(srcobj->relocbase + srcsym->st_value); - (void)memcpy(dstaddr, srcaddr, size); rdbg(("COPY %s %s %s --> src=%p dst=%p size %ld", dstobj->path, srcobj->path, name, srcaddr, (void *)dstaddr, (long)size)); + (void)memcpy(dstaddr, srcaddr, size); return (0); } #endif /* RTLD_INHIBIT_COPY_RELOCS */ @@ -149,6 +149,10 @@ _rtld_do_copy_relocations(const Obj_Entry *dstobj) } } } +#ifdef GNU_RELRO + if (_rtld_relro(dstobj, true) == -1) + return -1; +#endif #endif /* RTLD_INHIBIT_COPY_RELOCS */ return (0); @@ -225,18 +229,10 @@ _rtld_relocate_objects(Obj_Entry *first, bool bind_now) if (obj->pltgot != NULL) _rtld_setup_pltgot(obj); #ifdef GNU_RELRO - if (obj->relro_size > 0) { - if (mprotect(obj->relro_page, obj->relro_size, - PROT_READ) == -1) { - _rtld_error("%s: Cannot enforce relro " - "protection: %s", obj->path, - xstrerror(errno)); - return -1; - } - } + if (_rtld_relro(obj, false) == -1) + return -1; #endif } - return 0; } diff --git a/libexec/ld.elf_so/rtld.c b/libexec/ld.elf_so/rtld.c index e4f411421f72..ff45dacaf371 100644 --- a/libexec/ld.elf_so/rtld.c +++ b/libexec/ld.elf_so/rtld.c @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.c,v 1.194 2018/12/27 18:57:43 christos Exp $ */ +/* $NetBSD: rtld.c,v 1.195 2018/12/30 01:48:37 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -40,7 +40,7 @@ #include #ifndef lint -__RCSID("$NetBSD: rtld.c,v 1.194 2018/12/27 18:57:43 christos Exp $"); +__RCSID("$NetBSD: rtld.c,v 1.195 2018/12/30 01:48:37 christos Exp $"); #endif /* not lint */ #include @@ -1746,3 +1746,22 @@ _rtld_exclusive_exit(sigset_t *mask) sigprocmask(SIG_SETMASK, mask, NULL); } + +int +_rtld_relro(const Obj_Entry *obj, bool wantmain) +{ +#ifdef GNU_RELRO + if (obj->relro_size == 0) + return 0; + if (wantmain != (obj ==_rtld_objmain)) + return 0; + + dbg(("RELRO %s %p %lx\n", obj->path, obj->relro_page, obj->relro_size)); + if (mprotect(obj->relro_page, obj->relro_size, PROT_READ) == -1) { + _rtld_error("%s: Cannot enforce relro " "protection: %s", + obj->path, xstrerror(errno)); + return -1; + } +#endif + return 0; +} diff --git a/libexec/ld.elf_so/rtld.h b/libexec/ld.elf_so/rtld.h index 3219b2bb9a36..ade7e4147993 100644 --- a/libexec/ld.elf_so/rtld.h +++ b/libexec/ld.elf_so/rtld.h @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.h,v 1.135 2018/11/26 17:40:26 joerg Exp $ */ +/* $NetBSD: rtld.h,v 1.136 2018/12/30 01:48:37 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -372,6 +372,8 @@ void _rtld_shared_exit(void); void _rtld_exclusive_enter(sigset_t *); void _rtld_exclusive_exit(sigset_t *); +int _rtld_relro(const Obj_Entry *, bool); + /* expand.c */ size_t _rtld_expand_path(char *, size_t, const char *, const char *,\ const char *);