]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
[BZ #19129][ARM] Fix _dl_tlsdesc_resolve_hold to save r0
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 14 Oct 2015 15:58:41 +0000 (16:58 +0100)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 14 Oct 2015 16:01:12 +0000 (17:01 +0100)
_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
NEWS
sysdeps/arm/dl-tlsdesc.S

index 5b825cd3f4fb4f1bcc017e8fe335b5a6b39810ce..8a308891ea3d4a7f7487a64147bd13ddc43c11a7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-10-14  Szabolcs Nagy  <szabolcs.nagy@arm.com>
+
+       [BZ #19129]
+       * sysdeps/arm/dl-tlsdesc.S (_dl_tlsdesc_resolve_hold): Save and restore
+       r0 and r1.
+
 2015-10-14  Namhyung Kim  <namhyung@gmail.com>
 
        * manaual/argp.texi (Specifying Argp Parsers): Fix typo.
diff --git a/NEWS b/NEWS
index ed468ce7a6c15695629274d796a90e4ea652b014..fd33e079f6f5082e6ffe61a9d9f2a6899c1ce0ad 100644 (file)
--- 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 <regexp.h> has been removed.  Programs that require
   this header must be updated to use <regex.h> instead.
index e42ca68eda2ba78a5d9652e9600ded517a310e64..33a269573ecaef271ad392062dd4894cdbaebd86 100644 (file)
@@ -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)