diff options
Diffstat (limited to 'meta/recipes-core/glibc/glibc/0036-i386-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch')
-rw-r--r-- | meta/recipes-core/glibc/glibc/0036-i386-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/0036-i386-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch b/meta/recipes-core/glibc/glibc/0036-i386-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch new file mode 100644 index 0000000000..ad0a1147aa --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0036-i386-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch | |||
@@ -0,0 +1,124 @@ | |||
1 | From ddcacd91cc10ff92d6201eda87047d029c14158d Mon Sep 17 00:00:00 2001 | ||
2 | From: Szabolcs Nagy <szabolcs.nagy@arm.com> | ||
3 | Date: Thu, 11 Feb 2021 11:40:11 +0000 | ||
4 | Subject: [PATCH] i386: Avoid lazy relocation of tlsdesc [BZ #27137] | ||
5 | |||
6 | Lazy tlsdesc relocation is racy because the static tls optimization and | ||
7 | tlsdesc management operations are done without holding the dlopen lock. | ||
8 | |||
9 | This similar to the commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67 | ||
10 | for aarch64, but it fixes a different race: bug 27137. | ||
11 | |||
12 | On i386 the code is a bit more complicated than on x86_64 because both | ||
13 | rel and rela relocs are supported. | ||
14 | --- | ||
15 | sysdeps/i386/dl-machine.h | 76 ++++++++++++++++++--------------------- | ||
16 | 1 file changed, 34 insertions(+), 42 deletions(-) | ||
17 | --- | ||
18 | Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=ddcacd91cc10ff92d6201eda87047d029c14158d] | ||
19 | Signed-off-by: Akash Hadke <akash.hadke@kpit.com> | ||
20 | Signed-off-by: Akash Hadke <hadkeakash4@gmail.com> | ||
21 | --- | ||
22 | diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h | ||
23 | index 23e9cc3bfb..590b41d8d7 100644 | ||
24 | --- a/sysdeps/i386/dl-machine.h | ||
25 | +++ b/sysdeps/i386/dl-machine.h | ||
26 | @@ -688,50 +688,32 @@ elf_machine_lazy_rel (struct link_map *map, | ||
27 | } | ||
28 | else if (__glibc_likely (r_type == R_386_TLS_DESC)) | ||
29 | { | ||
30 | - struct tlsdesc volatile * __attribute__((__unused__)) td = | ||
31 | - (struct tlsdesc volatile *)reloc_addr; | ||
32 | - | ||
33 | - /* Handle relocations that reference the local *ABS* in a simple | ||
34 | - way, so as to preserve a potential addend. */ | ||
35 | - if (ELF32_R_SYM (reloc->r_info) == 0) | ||
36 | - td->entry = _dl_tlsdesc_resolve_abs_plus_addend; | ||
37 | - /* Given a known-zero addend, we can store a pointer to the | ||
38 | - reloc in the arg position. */ | ||
39 | - else if (td->arg == 0) | ||
40 | - { | ||
41 | - td->arg = (void*)reloc; | ||
42 | - td->entry = _dl_tlsdesc_resolve_rel; | ||
43 | - } | ||
44 | - else | ||
45 | - { | ||
46 | - /* We could handle non-*ABS* relocations with non-zero addends | ||
47 | - by allocating dynamically an arg to hold a pointer to the | ||
48 | - reloc, but that sounds pointless. */ | ||
49 | - const Elf32_Rel *const r = reloc; | ||
50 | - /* The code below was borrowed from elf_dynamic_do_rel(). */ | ||
51 | - const ElfW(Sym) *const symtab = | ||
52 | - (const void *) D_PTR (map, l_info[DT_SYMTAB]); | ||
53 | + const Elf32_Rel *const r = reloc; | ||
54 | + /* The code below was borrowed from elf_dynamic_do_rel(). */ | ||
55 | + const ElfW(Sym) *const symtab = | ||
56 | + (const void *) D_PTR (map, l_info[DT_SYMTAB]); | ||
57 | |||
58 | + /* Always initialize TLS descriptors completely at load time, in | ||
59 | + case static TLS is allocated for it that requires locking. */ | ||
60 | # ifdef RTLD_BOOTSTRAP | ||
61 | - /* The dynamic linker always uses versioning. */ | ||
62 | - assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL); | ||
63 | + /* The dynamic linker always uses versioning. */ | ||
64 | + assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL); | ||
65 | # else | ||
66 | - if (map->l_info[VERSYMIDX (DT_VERSYM)]) | ||
67 | + if (map->l_info[VERSYMIDX (DT_VERSYM)]) | ||
68 | # endif | ||
69 | - { | ||
70 | - const ElfW(Half) *const version = | ||
71 | - (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); | ||
72 | - ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; | ||
73 | - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], | ||
74 | - &map->l_versions[ndx], | ||
75 | - (void *) (l_addr + r->r_offset), skip_ifunc); | ||
76 | - } | ||
77 | + { | ||
78 | + const ElfW(Half) *const version = | ||
79 | + (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); | ||
80 | + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; | ||
81 | + elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], | ||
82 | + &map->l_versions[ndx], | ||
83 | + (void *) (l_addr + r->r_offset), skip_ifunc); | ||
84 | + } | ||
85 | # ifndef RTLD_BOOTSTRAP | ||
86 | - else | ||
87 | - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, | ||
88 | - (void *) (l_addr + r->r_offset), skip_ifunc); | ||
89 | + else | ||
90 | + elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, | ||
91 | + (void *) (l_addr + r->r_offset), skip_ifunc); | ||
92 | # endif | ||
93 | - } | ||
94 | } | ||
95 | else if (__glibc_unlikely (r_type == R_386_IRELATIVE)) | ||
96 | { | ||
97 | @@ -758,11 +740,21 @@ elf_machine_lazy_rela (struct link_map *map, | ||
98 | ; | ||
99 | else if (__glibc_likely (r_type == R_386_TLS_DESC)) | ||
100 | { | ||
101 | - struct tlsdesc volatile * __attribute__((__unused__)) td = | ||
102 | - (struct tlsdesc volatile *)reloc_addr; | ||
103 | + const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info); | ||
104 | + const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]); | ||
105 | + const ElfW (Sym) *sym = &symtab[symndx]; | ||
106 | + const struct r_found_version *version = NULL; | ||
107 | + | ||
108 | + if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL) | ||
109 | + { | ||
110 | + const ElfW (Half) *vernum = | ||
111 | + (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); | ||
112 | + version = &map->l_versions[vernum[symndx] & 0x7fff]; | ||
113 | + } | ||
114 | |||
115 | - td->arg = (void*)reloc; | ||
116 | - td->entry = _dl_tlsdesc_resolve_rela; | ||
117 | + /* Always initialize TLS descriptors completely at load time, in | ||
118 | + case static TLS is allocated for it that requires locking. */ | ||
119 | + elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc); | ||
120 | } | ||
121 | else if (__glibc_unlikely (r_type == R_386_IRELATIVE)) | ||
122 | { | ||
123 | -- | ||
124 | 2.27.0 | ||