This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Protect _dl_profile_fixup data-dependency order [BZ #23690]
- From: Tulio Magno Quites Machado Filho <tuliom at linux dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Date: Wed, 19 Sep 2018 18:48:29 -0300
- Subject: [PATCH] Protect _dl_profile_fixup data-dependency order [BZ #23690]
The field reloc_result->addr is used to indicate if the rest of the
fields of reloc_result have already been written, creating a
data-dependency order.
Reading reloc_result->addr to the variable value requires to complete
before reading the rest of the fields of reloc_result.
Likewise, the writes to the other fields of the reloc_result must
complete before reloc_result-addr is updated.
2018-09-19 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
[BZ #23690]
* elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory
modification order when accessing reloc_result->addr.
Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
---
elf/dl-runtime.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 63bbc89776..6518e66fd6 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -183,9 +183,16 @@ _dl_profile_fixup (
/* This is the address in the array where we store the result of previous
relocations. */
struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
- DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
- DL_FIXUP_VALUE_TYPE value = *resultp;
+ /* CONCURRENCY NOTES:
+
+ The following code uses reloc_result->addr to indicate if it is the first
+ time this object is being relocated.
+ Reading/Writing from/to reloc_result->addr must not happen before previous
+ writes to reloc_result complete as they could end-up with an incomplete
+ struct. */
+ DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
+ DL_FIXUP_VALUE_TYPE value = atomic_load_acquire(resultp);
if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
{
/* This is the first time we have to relocate this object. */
@@ -346,7 +353,10 @@ _dl_profile_fixup (
/* Store the result for later runs. */
if (__glibc_likely (! GLRO(dl_bind_not)))
- *resultp = value;
+ /* Guarantee all previous writes complete before
+ resultp (reloc_result->addr) is updated. See CONCURRENCY NOTES
+ earlier */
+ atomic_store_release(resultp, value);
}
/* By default we do not call the pltexit function. */
--
2.14.4