diff options
Diffstat (limited to 'meta/recipes-core/glibc/glibc/0030-elf-Refactor_dl_update-slotinfo-to-avoid-use-after-free.patch')
-rw-r--r-- | meta/recipes-core/glibc/glibc/0030-elf-Refactor_dl_update-slotinfo-to-avoid-use-after-free.patch | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/0030-elf-Refactor_dl_update-slotinfo-to-avoid-use-after-free.patch b/meta/recipes-core/glibc/glibc/0030-elf-Refactor_dl_update-slotinfo-to-avoid-use-after-free.patch new file mode 100644 index 0000000000..dba491f4dc --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0030-elf-Refactor_dl_update-slotinfo-to-avoid-use-after-free.patch | |||
@@ -0,0 +1,66 @@ | |||
1 | From c0669ae1a629e16b536bf11cdd0865e0dbcf4bee Mon Sep 17 00:00:00 2001 | ||
2 | From: Szabolcs Nagy <szabolcs.nagy@arm.com> | ||
3 | Date: Wed, 30 Dec 2020 21:52:38 +0000 | ||
4 | Subject: [PATCH] elf: Refactor _dl_update_slotinfo to avoid use after free | ||
5 | |||
6 | map is not valid to access here because it can be freed by a concurrent | ||
7 | dlclose: during tls access (via __tls_get_addr) _dl_update_slotinfo is | ||
8 | called without holding dlopen locks. So don't check the modid of map. | ||
9 | |||
10 | The map == 0 and map != 0 code paths can be shared (avoiding the dtv | ||
11 | resize in case of map == 0 is just an optimization: larger dtv than | ||
12 | necessary would be fine too). | ||
13 | |||
14 | Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> | ||
15 | --- | ||
16 | elf/dl-tls.c | 21 +++++---------------- | ||
17 | 1 file changed, 5 insertions(+), 16 deletions(-) | ||
18 | --- | ||
19 | Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=c0669ae1a629e16b536bf11cdd0865e0dbcf4bee] | ||
20 | Signed-off-by: Akash Hadke <akash.hadke@kpit.com> | ||
21 | Signed-off-by: Akash Hadke <hadkeakash4@gmail.com> | ||
22 | --- | ||
23 | diff --git a/elf/dl-tls.c b/elf/dl-tls.c | ||
24 | index 24d00c14ef..f8b32b3ecb 100644 | ||
25 | --- a/elf/dl-tls.c | ||
26 | +++ b/elf/dl-tls.c | ||
27 | @@ -743,6 +743,8 @@ _dl_update_slotinfo (unsigned long int req_modid) | ||
28 | { | ||
29 | for (size_t cnt = total == 0 ? 1 : 0; cnt < listp->len; ++cnt) | ||
30 | { | ||
31 | + size_t modid = total + cnt; | ||
32 | + | ||
33 | size_t gen = listp->slotinfo[cnt].gen; | ||
34 | |||
35 | if (gen > new_gen) | ||
36 | @@ -758,25 +760,12 @@ _dl_update_slotinfo (unsigned long int req_modid) | ||
37 | |||
38 | /* If there is no map this means the entry is empty. */ | ||
39 | struct link_map *map = listp->slotinfo[cnt].map; | ||
40 | - if (map == NULL) | ||
41 | - { | ||
42 | - if (dtv[-1].counter >= total + cnt) | ||
43 | - { | ||
44 | - /* If this modid was used at some point the memory | ||
45 | - might still be allocated. */ | ||
46 | - free (dtv[total + cnt].pointer.to_free); | ||
47 | - dtv[total + cnt].pointer.val = TLS_DTV_UNALLOCATED; | ||
48 | - dtv[total + cnt].pointer.to_free = NULL; | ||
49 | - } | ||
50 | - | ||
51 | - continue; | ||
52 | - } | ||
53 | - | ||
54 | /* Check whether the current dtv array is large enough. */ | ||
55 | - size_t modid = map->l_tls_modid; | ||
56 | - assert (total + cnt == modid); | ||
57 | if (dtv[-1].counter < modid) | ||
58 | { | ||
59 | + if (map == NULL) | ||
60 | + continue; | ||
61 | + | ||
62 | /* Resize the dtv. */ | ||
63 | dtv = _dl_resize_dtv (dtv); | ||
64 | |||
65 | -- | ||
66 | 2.27.0 | ||