From 1fae5a6800b07d0a8225664ac65a628bbe98cae7 Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Wed, 14 Oct 2015 16:58:41 +0100 Subject: [BZ #19129][ARM] Fix _dl_tlsdesc_resolve_hold to save r0 _dl_tlsdesc_resolve_hold calls into a C function that clobbers r0, but it assumes the original argument is still in r0 after the call. This can cause crash in case of concurrent TLS access when TLSDESC is in use (-mtls-dialect=gnu2). Run into this while fixing BZ 18572. Both r0 and r1 are saved/restored so the stack remains 8 byte aligned. [BZ #19129] * sysdeps/arm/dl-tlsdesc.S (_dl_tlsdesc_resolve_hold): Save and restore r0 and r1. --- ChangeLog | 6 ++++++ NEWS | 2 +- sysdeps/arm/dl-tlsdesc.S | 27 ++++++++++++++++++--------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b825cd3f4..8a308891ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-10-14 Szabolcs Nagy + + [BZ #19129] + * sysdeps/arm/dl-tlsdesc.S (_dl_tlsdesc_resolve_hold): Save and restore + r0 and r1. + 2015-10-14 Namhyung Kim * manaual/argp.texi (Specifying Argp Parsers): Fix typo. diff --git a/NEWS b/NEWS index ed468ce7a6..fd33e079f6 100644 --- a/NEWS +++ b/NEWS @@ -20,7 +20,7 @@ Version 2.23 18966, 18967, 18969, 18970, 18977, 18980, 18981, 18985, 19003, 19007, 19012, 19016, 19018, 19032, 19046, 19049, 19050, 19059, 19071, 19074, 19076, 19077, 19078, 19079, 19085, 19086, 19088, 19094, 19095, 19124, - 19125 + 19125, 19129 * The obsolete header has been removed. Programs that require this header must be updated to use instead. diff --git a/sysdeps/arm/dl-tlsdesc.S b/sysdeps/arm/dl-tlsdesc.S index e42ca68eda..33a269573e 100644 --- a/sysdeps/arm/dl-tlsdesc.S +++ b/sysdeps/arm/dl-tlsdesc.S @@ -196,21 +196,30 @@ _dl_tlsdesc_lazy_resolver: eabi_fnstart .align 2 _dl_tlsdesc_resolve_hold: - eabi_save ({r2,r3,ip,lr}) - push {r2, r3, ip, lr} - cfi_adjust_cfa_offset (16) - cfi_rel_offset (r2, 0) - cfi_rel_offset (r3, 4) - cfi_rel_offset (ip, 8) - cfi_rel_offset (lr, 12) + /* r0 is saved so its original value can be used after the call and + r1 is saved only to keep the stack aligned. (r0 points to the tls + descriptor, it is passed to _dl_tlsdesc_resolve_hold_fixup which + is a void function that may clobber r0, later r0 is used to load + the new resolver.) */ + eabi_save ({r0,r1,r2,r3,ip,lr}) + push {r0, r1, r2, r3, ip, lr} + cfi_adjust_cfa_offset (24) + cfi_rel_offset (r0, 0) + cfi_rel_offset (r1, 4) + cfi_rel_offset (r2, 8) + cfi_rel_offset (r3, 12) + cfi_rel_offset (ip, 16) + cfi_rel_offset (lr, 20) adr r1, _dl_tlsdesc_resolve_hold bl _dl_tlsdesc_resolve_hold_fixup - pop {r2, r3, ip, lr} - cfi_adjust_cfa_offset (-16) + pop {r0, r1, r2, r3, ip, lr} + cfi_adjust_cfa_offset (-24) cfi_restore (lr) cfi_restore (ip) cfi_restore (r3) cfi_restore (r2) + cfi_restore (r1) + cfi_restore (r0) sfi_breg r0, \ ldr r1, [\B, #4] BX (r1) -- cgit 1.4.1