From patchwork Wed Jun 6 14:01:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 27657 Received: (qmail 66485 invoked by alias); 6 Jun 2018 14:02:01 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 66367 invoked by uid 89); 6 Jun 2018 14:01:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=audit, protect X-HELO: mx1.redhat.com Date: Wed, 06 Jun 2018 16:01:49 +0200 To: libc-alpha@sourceware.org Subject: [PATCH] ld.so: Defer applying RELRO protection User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20180606140149.F3EB5439942E1@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) This is a prerequisite of a future change which applies additional cross-object relocations after _dl_relocate_object has been called. 2018-06-05 Florian Weimer * sysdeps/generic/ldsodefs.h (_dl_relocate_apply_relro): Declare. * elf/rtld.c (relocate_doit): Add comment. (dl_main): Call _dl_relocate_apply_relro. * elf/dl-open.c (dl_open_worker): Likewise. * elf/dl-reloc.c (_dl_relocate_object): Do not call _dl_protect_relro. (_dl_relocate_apply_relro): New function. diff --git a/elf/dl-open.c b/elf/dl-open.c index 9dde4acfbc..92b498eb2d 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -491,6 +491,8 @@ TLS generation counter wrapped! Please report this.")); } } + _dl_relocate_apply_relro (new); + /* Notify the debugger all new objects have been relocated. */ if (relocation_in_progress) LIBC_PROBE (reloc_complete, 3, args->nsid, r, new); diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 053916eeae..8fed33f3dc 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -299,14 +299,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], textrels = textrels->next; } - - /* In case we can protect the data now that the relocations are - done, do it. */ - if (l->l_relro_size != 0) - _dl_protect_relro (l); } - void _dl_protect_relro (struct link_map *l) { @@ -326,6 +320,19 @@ cannot apply additional memory protection after relocation"); } } +void +_dl_relocate_apply_relro (struct link_map *new) +{ + struct link_map **lp = new->l_searchlist.r_list; + struct link_map **end = lp + new->l_searchlist.r_nlist; + for (; lp < end; ++lp) + { + struct link_map *l = *lp; + if (l->l_relro_size) + _dl_protect_relro (l); + } +} + void __attribute_noinline__ _dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt) diff --git a/elf/rtld.c b/elf/rtld.c index e7681ebb1f..10062e48f6 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -574,6 +574,7 @@ struct version_check_args int dotrace; }; +/* Callback function used during tracing. */ static void relocate_doit (void *a) { @@ -2251,6 +2252,17 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", HP_TIMING_ACCUM_NT (relocate_time, add); } + /* Activate RELRO protection. In the prelink case, this was already + done earlier. */ + if (! prelinked) + { + /* Make sure that this covers the dynamic linker as well. + TODO: rtld_multiple_ref is always true because libc.so needs + the dynamic linker internally. */ + assert (rtld_multiple_ref); + _dl_relocate_apply_relro (main_map); + } + /* Do any necessary cleanups for the startup OS interface code. We do these now so that no calls are made after rtld re-relocation which might be resolved to different functions than we expect. diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 95dc87519b..8f9952ab93 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -937,6 +937,11 @@ extern void _dl_relocate_object (struct link_map *map, int reloc_mode, int consider_profiling) attribute_hidden; +/* Apply RELRO protection for all objects on the search path of NEW. + This is the final step of relocation processing for freshly loaded + objects. */ +void _dl_relocate_apply_relro (struct link_map *new) attribute_hidden; + /* Protect PT_GNU_RELRO area. */ extern void _dl_protect_relro (struct link_map *map) attribute_hidden;