From patchwork Wed Sep 19 21:48:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tulio Magno Quites Machado Filho X-Patchwork-Id: 29479 Received: (qmail 34864 invoked by alias); 19 Sep 2018 21:48:46 -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 34807 invoked by uid 89); 19 Sep 2018 21:48:44 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KHOP_DYNAMIC, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=Guarantee, Writing, Hx-languages-length:2149 X-HELO: mx0a-001b2d01.pphosted.com From: Tulio Magno Quites Machado Filho To: libc-alpha@sourceware.org Subject: [PATCH] Protect _dl_profile_fixup data-dependency order [BZ #23690] Date: Wed, 19 Sep 2018 18:48:29 -0300 x-cbid: 18091921-0004-0000-0000-0000148CEEC7 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009736; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000266; SDB=6.01090759; UDB=6.00563526; IPR=6.00870780; MB=3.00023396; MTD=3.00000008; XFM=3.00000015; UTC=2018-09-19 21:48:38 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18091921-0005-0000-0000-000088DE469C Message-Id: <20180919214829.20551-1-tuliom@linux.ibm.com> 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 [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 --- 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. */