summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/glibc/glibc
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/glibc/glibc')
-rw-r--r--meta/recipes-core/glibc/glibc/0030-elf-Refactor_dl_update-slotinfo-to-avoid-use-after-free.patch66
-rw-r--r--meta/recipes-core/glibc/glibc/0031-elf-Fix-data-races-in-pthread_create-and-TLS-access-BZ-19329.patch191
-rw-r--r--meta/recipes-core/glibc/glibc/0032-elf-Use-relaxed-atomics-for-racy-accesses-BZ-19329.patch206
-rw-r--r--meta/recipes-core/glibc/glibc/0033-elf-Add-test-case-for-BZ-19329.patch144
-rw-r--r--meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch180
-rw-r--r--meta/recipes-core/glibc/glibc/0035-x86_64-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch56
-rw-r--r--meta/recipes-core/glibc/glibc/0036-i386-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch124
-rw-r--r--meta/recipes-core/glibc/glibc/0037-Avoid-deadlock-between-pthread_create-and-ctors.patch276
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2019-25013.patch135
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2020-29562.patch156
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2021-33574_1.patch68
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2021-33574_2.patch73
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2021-38604.patch41
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2023-0687.patch82
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2023-4813.patch986
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2023-4911.patch63
-rw-r--r--meta/recipes-core/glibc/glibc/check-test-wrapper11
17 files changed, 2566 insertions, 292 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 @@
1From c0669ae1a629e16b536bf11cdd0865e0dbcf4bee Mon Sep 17 00:00:00 2001
2From: Szabolcs Nagy <szabolcs.nagy@arm.com>
3Date: Wed, 30 Dec 2020 21:52:38 +0000
4Subject: [PATCH] elf: Refactor _dl_update_slotinfo to avoid use after free
5
6map is not valid to access here because it can be freed by a concurrent
7dlclose: during tls access (via __tls_get_addr) _dl_update_slotinfo is
8called without holding dlopen locks. So don't check the modid of map.
9
10The map == 0 and map != 0 code paths can be shared (avoiding the dtv
11resize in case of map == 0 is just an optimization: larger dtv than
12necessary would be fine too).
13
14Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
15---
16 elf/dl-tls.c | 21 +++++----------------
17 1 file changed, 5 insertions(+), 16 deletions(-)
18---
19Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=c0669ae1a629e16b536bf11cdd0865e0dbcf4bee]
20Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
21Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
22---
23diff --git a/elf/dl-tls.c b/elf/dl-tls.c
24index 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--
662.27.0
diff --git a/meta/recipes-core/glibc/glibc/0031-elf-Fix-data-races-in-pthread_create-and-TLS-access-BZ-19329.patch b/meta/recipes-core/glibc/glibc/0031-elf-Fix-data-races-in-pthread_create-and-TLS-access-BZ-19329.patch
new file mode 100644
index 0000000000..25beee1d50
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0031-elf-Fix-data-races-in-pthread_create-and-TLS-access-BZ-19329.patch
@@ -0,0 +1,191 @@
1From 1387ad6225c2222f027790e3f460e31aa5dd2c54 Mon Sep 17 00:00:00 2001
2From: Szabolcs Nagy <szabolcs.nagy@arm.com>
3Date: Wed, 30 Dec 2020 19:19:37 +0000
4Subject: [PATCH] elf: Fix data races in pthread_create and TLS access [BZ
5 #19329]
6
7DTV setup at thread creation (_dl_allocate_tls_init) is changed
8to take the dlopen lock, GL(dl_load_lock). Avoiding data races
9here without locks would require design changes: the map that is
10accessed for static TLS initialization here may be concurrently
11freed by dlclose. That use after free may be solved by only
12locking around static TLS setup or by ensuring dlclose does not
13free modules with static TLS, however currently every link map
14with TLS has to be accessed at least to see if it needs static
15TLS. And even if that's solved, still a lot of atomics would be
16needed to synchronize DTV related globals without a lock. So fix
17both bug 19329 and bug 27111 with a lock that prevents DTV setup
18running concurrently with dlopen or dlclose.
19
20_dl_update_slotinfo at TLS access still does not use any locks
21so CONCURRENCY NOTES are added to explain the synchronization.
22The early exit from the slotinfo walk when max_modid is reached
23is not strictly necessary, but does not hurt either.
24
25An incorrect acquire load was removed from _dl_resize_dtv: it
26did not synchronize with any release store or fence and
27synchronization is now handled separately at thread creation
28and TLS access time.
29
30There are still a number of racy read accesses to globals that
31will be changed to relaxed MO atomics in a followup patch. This
32should not introduce regressions compared to existing behaviour
33and avoid cluttering the main part of the fix.
34
35Not all TLS access related data races got fixed here: there are
36additional races at lazy tlsdesc relocations see bug 27137.
37
38Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
39---
40 elf/dl-tls.c | 63 +++++++++++++++++++++++++++++++++++++++-------------
41 1 file changed, 47 insertions(+), 16 deletions(-)
42---
43Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=1387ad6225c2222f027790e3f460e31aa5dd2c54]
44Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
45Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
46---
47diff --git a/elf/dl-tls.c b/elf/dl-tls.c
48index 6baff0c1ea..94f3cdbae0 100644
49--- a/elf/dl-tls.c
50+++ b/elf/dl-tls.c
51@@ -475,14 +475,11 @@ extern dtv_t _dl_static_dtv[];
52 #endif
53
54 static dtv_t *
55-_dl_resize_dtv (dtv_t *dtv)
56+_dl_resize_dtv (dtv_t *dtv, size_t max_modid)
57 {
58 /* Resize the dtv. */
59 dtv_t *newp;
60- /* Load GL(dl_tls_max_dtv_idx) atomically since it may be written to by
61- other threads concurrently. */
62- size_t newsize
63- = atomic_load_acquire (&GL(dl_tls_max_dtv_idx)) + DTV_SURPLUS;
64+ size_t newsize = max_modid + DTV_SURPLUS;
65 size_t oldsize = dtv[-1].counter;
66
67 if (dtv == GL(dl_initial_dtv))
68@@ -528,11 +525,14 @@ _dl_allocate_tls_init (void *result)
69 size_t total = 0;
70 size_t maxgen = 0;
71
72+ /* Protects global dynamic TLS related state. */
73+ __rtld_lock_lock_recursive (GL(dl_load_lock));
74+
75 /* Check if the current dtv is big enough. */
76 if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
77 {
78 /* Resize the dtv. */
79- dtv = _dl_resize_dtv (dtv);
80+ dtv = _dl_resize_dtv (dtv, GL(dl_tls_max_dtv_idx));
81
82 /* Install this new dtv in the thread data structures. */
83 INSTALL_DTV (result, &dtv[-1]);
84@@ -600,6 +600,7 @@ _dl_allocate_tls_init (void *result)
85 listp = listp->next;
86 assert (listp != NULL);
87 }
88+ __rtld_lock_unlock_recursive (GL(dl_load_lock));
89
90 /* The DTV version is up-to-date now. */
91 dtv[0].counter = maxgen;
92@@ -734,12 +735,29 @@ _dl_update_slotinfo (unsigned long int req_modid)
93
94 if (dtv[0].counter < listp->slotinfo[idx].gen)
95 {
96- /* The generation counter for the slot is higher than what the
97- current dtv implements. We have to update the whole dtv but
98- only those entries with a generation counter <= the one for
99- the entry we need. */
100+ /* CONCURRENCY NOTES:
101+
102+ Here the dtv needs to be updated to new_gen generation count.
103+
104+ This code may be called during TLS access when GL(dl_load_lock)
105+ is not held. In that case the user code has to synchronize with
106+ dlopen and dlclose calls of relevant modules. A module m is
107+ relevant if the generation of m <= new_gen and dlclose of m is
108+ synchronized: a memory access here happens after the dlopen and
109+ before the dlclose of relevant modules. The dtv entries for
110+ relevant modules need to be updated, other entries can be
111+ arbitrary.
112+
113+ This e.g. means that the first part of the slotinfo list can be
114+ accessed race free, but the tail may be concurrently extended.
115+ Similarly relevant slotinfo entries can be read race free, but
116+ other entries are racy. However updating a non-relevant dtv
117+ entry does not affect correctness. For a relevant module m,
118+ max_modid >= modid of m. */
119 size_t new_gen = listp->slotinfo[idx].gen;
120 size_t total = 0;
121+ size_t max_modid = atomic_load_relaxed (&GL(dl_tls_max_dtv_idx));
122+ assert (max_modid >= req_modid);
123
124 /* We have to look through the entire dtv slotinfo list. */
125 listp = GL(dl_tls_dtv_slotinfo_list);
126@@ -749,12 +767,14 @@ _dl_update_slotinfo (unsigned long int req_modid)
127 {
128 size_t modid = total + cnt;
129
130+ /* Later entries are not relevant. */
131+ if (modid > max_modid)
132+ break;
133+
134 size_t gen = listp->slotinfo[cnt].gen;
135
136 if (gen > new_gen)
137- /* This is a slot for a generation younger than the
138- one we are handling now. It might be incompletely
139- set up so ignore it. */
140+ /* Not relevant. */
141 continue;
142
143 /* If the entry is older than the current dtv layout we
144@@ -771,7 +791,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
145 continue;
146
147 /* Resize the dtv. */
148- dtv = _dl_resize_dtv (dtv);
149+ dtv = _dl_resize_dtv (dtv, max_modid);
150
151 assert (modid <= dtv[-1].counter);
152
153@@ -793,8 +813,17 @@ _dl_update_slotinfo (unsigned long int req_modid)
154 }
155
156 total += listp->len;
157+ if (total > max_modid)
158+ break;
159+
160+ /* Synchronize with _dl_add_to_slotinfo. Ideally this would
161+ be consume MO since we only need to order the accesses to
162+ the next node after the read of the address and on most
163+ hardware (other than alpha) a normal load would do that
164+ because of the address dependency. */
165+ listp = atomic_load_acquire (&listp->next);
166 }
167- while ((listp = listp->next) != NULL);
168+ while (listp != NULL);
169
170 /* This will be the new maximum generation counter. */
171 dtv[0].counter = new_gen;
172@@ -986,7 +1015,7 @@ _dl_add_to_slotinfo (struct link_map *l, bool do_add)
173 the first slot. */
174 assert (idx == 0);
175
176- listp = prevp->next = (struct dtv_slotinfo_list *)
177+ listp = (struct dtv_slotinfo_list *)
178 malloc (sizeof (struct dtv_slotinfo_list)
179 + TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
180 if (listp == NULL)
181@@ -1000,6 +1029,8 @@ cannot create TLS data structures"));
182 listp->next = NULL;
183 memset (listp->slotinfo, '\0',
184 TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
185+ /* Synchronize with _dl_update_slotinfo. */
186+ atomic_store_release (&prevp->next, listp);
187 }
188
189 /* Add the information into the slotinfo data structure. */
190--
1912.27.0
diff --git a/meta/recipes-core/glibc/glibc/0032-elf-Use-relaxed-atomics-for-racy-accesses-BZ-19329.patch b/meta/recipes-core/glibc/glibc/0032-elf-Use-relaxed-atomics-for-racy-accesses-BZ-19329.patch
new file mode 100644
index 0000000000..eb8ef3161c
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0032-elf-Use-relaxed-atomics-for-racy-accesses-BZ-19329.patch
@@ -0,0 +1,206 @@
1From f4f8f4d4e0f92488431b268c8cd9555730b9afe9 Mon Sep 17 00:00:00 2001
2From: Szabolcs Nagy <szabolcs.nagy@arm.com>
3Date: Wed, 30 Dec 2020 19:19:37 +0000
4Subject: [PATCH] elf: Use relaxed atomics for racy accesses [BZ #19329]
5
6This is a follow up patch to the fix for bug 19329. This adds relaxed
7MO atomics to accesses that were previously data races but are now
8race conditions, and where relaxed MO is sufficient.
9
10The race conditions all follow the pattern that the write is behind the
11dlopen lock, but a read can happen concurrently (e.g. during tls access)
12without holding the lock. For slotinfo entries the read value only
13matters if it reads from a synchronized write in dlopen or dlclose,
14otherwise the related dtv entry is not valid to access so it is fine
15to leave it in an inconsistent state. The same applies for
16GL(dl_tls_max_dtv_idx) and GL(dl_tls_generation), but there the
17algorithm relies on the fact that the read of the last synchronized
18write is an increasing value.
19
20Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
21---
22 elf/dl-close.c | 20 +++++++++++++-------
23 elf/dl-open.c | 5 ++++-
24 elf/dl-tls.c | 31 +++++++++++++++++++++++--------
25 sysdeps/x86_64/dl-tls.c | 3 ++-
26 4 files changed, 42 insertions(+), 17 deletions(-)
27---
28Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=f4f8f4d4e0f92488431b268c8cd9555730b9afe9]
29Comment: Hunks from elf/dl-open.c and elf/dl-tls.c are refreshed due to offset change.
30Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
31Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
32---
33diff --git a/elf/dl-close.c b/elf/dl-close.c
34index c51becd06b..3720e47dd1 100644
35--- a/elf/dl-close.c
36+++ b/elf/dl-close.c
37@@ -79,9 +79,10 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
38 {
39 assert (old_map->l_tls_modid == idx);
40
41- /* Mark the entry as unused. */
42- listp->slotinfo[idx - disp].gen = GL(dl_tls_generation) + 1;
43- listp->slotinfo[idx - disp].map = NULL;
44+ /* Mark the entry as unused. These can be read concurrently. */
45+ atomic_store_relaxed (&listp->slotinfo[idx - disp].gen,
46+ GL(dl_tls_generation) + 1);
47+ atomic_store_relaxed (&listp->slotinfo[idx - disp].map, NULL);
48 }
49
50 /* If this is not the last currently used entry no need to look
51@@ -96,8 +97,8 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
52
53 if (listp->slotinfo[idx - disp].map != NULL)
54 {
55- /* Found a new last used index. */
56- GL(dl_tls_max_dtv_idx) = idx;
57+ /* Found a new last used index. This can be read concurrently. */
58+ atomic_store_relaxed (&GL(dl_tls_max_dtv_idx), idx);
59 return true;
60 }
61 }
62@@ -571,7 +572,9 @@ _dl_close_worker (struct link_map *map, bool force)
63 GL(dl_tls_dtv_slotinfo_list), 0,
64 imap->l_init_called))
65 /* All dynamically loaded modules with TLS are unloaded. */
66- GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem);
67+ /* Can be read concurrently. */
68+ atomic_store_relaxed (&GL(dl_tls_max_dtv_idx),
69+ GL(dl_tls_static_nelem));
70
71 if (imap->l_tls_offset != NO_TLS_OFFSET
72 && imap->l_tls_offset != FORCED_DYNAMIC_TLS_OFFSET)
73@@ -769,8 +772,11 @@ _dl_close_worker (struct link_map *map, bool force)
74 /* If we removed any object which uses TLS bump the generation counter. */
75 if (any_tls)
76 {
77- if (__glibc_unlikely (++GL(dl_tls_generation) == 0))
78+ size_t newgen = GL(dl_tls_generation) + 1;
79+ if (__glibc_unlikely (newgen == 0))
80 _dl_fatal_printf ("TLS generation counter wrapped! Please report as described in "REPORT_BUGS_TO".\n");
81+ /* Can be read concurrently. */
82+ atomic_store_relaxed (&GL(dl_tls_generation), newgen);
83
84 if (tls_free_end == GL(dl_tls_static_used))
85 GL(dl_tls_static_used) = tls_free_start;
86diff --git a/elf/dl-open.c b/elf/dl-open.c
87index 09f0df7d38..bb79ef00f1 100644
88--- a/elf/dl-open.c
89+++ b/elf/dl-open.c
90@@ -387,9 +387,12 @@
91 }
92 }
93
94- if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
95+ size_t newgen = GL(dl_tls_generation) + 1;
96+ if (__glibc_unlikely (newgen == 0))
97 _dl_fatal_printf (N_("\
98 TLS generation counter wrapped! Please report this."));
99+ /* Can be read concurrently. */
100+ atomic_store_relaxed (&GL(dl_tls_generation), newgen);
101
102 /* We need a second pass for static tls data, because
103 _dl_update_slotinfo must not be run while calls to
104diff --git a/elf/dl-tls.c b/elf/dl-tls.c
105index 94f3cdbae0..dc69cd984e 100644
106--- a/elf/dl-tls.c
107+++ b/elf/dl-tls.c
108@@ -96,7 +96,9 @@
109 /* No gaps, allocate a new entry. */
110 nogaps:
111
112- result = ++GL(dl_tls_max_dtv_idx);
113+ result = GL(dl_tls_max_dtv_idx) + 1;
114+ /* Can be read concurrently. */
115+ atomic_store_relaxed (&GL(dl_tls_max_dtv_idx), result);
116 }
117
118 return result;
119@@ -279,10 +281,12 @@
120 dtv_t *dtv;
121 size_t dtv_length;
122
123+ /* Relaxed MO, because the dtv size is later rechecked, not relied on. */
124+ size_t max_modid = atomic_load_relaxed (&GL(dl_tls_max_dtv_idx));
125 /* We allocate a few more elements in the dtv than are needed for the
126 initial set of modules. This should avoid in most cases expansions
127 of the dtv. */
128- dtv_length = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS;
129+ dtv_length = max_modid + DTV_SURPLUS;
130 dtv = calloc (dtv_length + 2, sizeof (dtv_t));
131 if (dtv != NULL)
132 {
133@@ -687,7 +691,7 @@
134 if (modid > max_modid)
135 break;
136
137- size_t gen = listp->slotinfo[cnt].gen;
138+ size_t gen = atomic_load_relaxed (&listp->slotinfo[cnt].gen);
139
140 if (gen > new_gen)
141 /* Not relevant. */
142@@ -699,7 +703,8 @@
143 continue;
144
145 /* If there is no map this means the entry is empty. */
146- struct link_map *map = listp->slotinfo[cnt].map;
147+ struct link_map *map
148+ = atomic_load_relaxed (&listp->slotinfo[cnt].map);
149 /* Check whether the current dtv array is large enough. */
150 if (dtv[-1].counter < modid)
151 {
152@@ -843,7 +848,12 @@
153 {
154 dtv_t *dtv = THREAD_DTV ();
155
156- if (__glibc_unlikely (dtv[0].counter != GL(dl_tls_generation)))
157+ /* Update is needed if dtv[0].counter < the generation of the accessed
158+ module. The global generation counter is used here as it is easier
159+ to check. Synchronization for the relaxed MO access is guaranteed
160+ by user code, see CONCURRENCY NOTES in _dl_update_slotinfo. */
161+ size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
162+ if (__glibc_unlikely (dtv[0].counter != gen))
163 return update_get_addr (GET_ADDR_PARAM);
164
165 void *p = dtv[GET_ADDR_MODULE].pointer.val;
166@@ -866,7 +876,10 @@
167 return NULL;
168
169 dtv_t *dtv = THREAD_DTV ();
170- if (__glibc_unlikely (dtv[0].counter != GL(dl_tls_generation)))
171+ /* This may be called without holding the GL(dl_load_lock). Reading
172+ arbitrary gen value is fine since this is best effort code. */
173+ size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
174+ if (__glibc_unlikely (dtv[0].counter != gen))
175 {
176 /* This thread's DTV is not completely current,
177 but it might already cover this module. */
178@@ -961,7 +974,9 @@
179 /* Add the information into the slotinfo data structure. */
180 if (do_add)
181 {
182- listp->slotinfo[idx].map = l;
183- listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
184+ /* Can be read concurrently. See _dl_update_slotinfo. */
185+ atomic_store_relaxed (&listp->slotinfo[idx].map, l);
186+ atomic_store_relaxed (&listp->slotinfo[idx].gen,
187+ GL(dl_tls_generation) + 1);
188 }
189 }
190
191diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c
192index 6595f6615b..24ef560b71 100644
193--- a/sysdeps/x86_64/dl-tls.c
194+++ b/sysdeps/x86_64/dl-tls.c
195@@ -40,7 +40,8 @@ __tls_get_addr_slow (GET_ADDR_ARGS)
196 {
197 dtv_t *dtv = THREAD_DTV ();
198
199- if (__glibc_unlikely (dtv[0].counter != GL(dl_tls_generation)))
200+ size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
201+ if (__glibc_unlikely (dtv[0].counter != gen))
202 return update_get_addr (GET_ADDR_PARAM);
203
204 return tls_get_addr_tail (GET_ADDR_PARAM, dtv, NULL);
205--
2062.27.0
diff --git a/meta/recipes-core/glibc/glibc/0033-elf-Add-test-case-for-BZ-19329.patch b/meta/recipes-core/glibc/glibc/0033-elf-Add-test-case-for-BZ-19329.patch
new file mode 100644
index 0000000000..f22e52ea99
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0033-elf-Add-test-case-for-BZ-19329.patch
@@ -0,0 +1,144 @@
1From 9d0e30329c23b5ad736fda3f174208c25970dbce Mon Sep 17 00:00:00 2001
2From: Szabolcs Nagy <szabolcs.nagy@arm.com>
3Date: Tue, 13 Dec 2016 12:28:41 +0000
4Subject: [PATCH] elf: Add test case for [BZ #19329]
5
6Test concurrent dlopen and pthread_create when the loaded modules have
7TLS. This triggers dl-tls assertion failures more reliably than the
8nptl/tst-stack4 test.
9
10The dlopened module has 100 DT_NEEDED dependencies with TLS, they were
11reused from an existing TLS test. The number of created threads during
12dlopen depends on filesystem speed and hardware, but at most 3 threads
13are alive at a time to limit resource usage.
14
15Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
16---
17 elf/Makefile | 9 ++++--
18 elf/tst-tls21.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++
19 elf/tst-tls21mod.c | 1 +
20 3 files changed, 76 insertions(+), 2 deletions(-)
21 create mode 100644 elf/tst-tls21.c
22 create mode 100644 elf/tst-tls21mod.c
23---
24Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=9d0e30329c23b5ad736fda3f174208c25970dbce]
25Comment: Hunks from elf/Makefile are refreshed as per glibc 2.31 codebase.
26Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
27Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
28---
29diff --git a/elf/Makefile b/elf/Makefile
30index d3e909637a..3241cb6046 100644
31--- a/elf/Makefile
32+++ b/elf/Makefile
33@@ -201,7 +201,7 @@
34 tst-unwind-ctor tst-unwind-main tst-audit13 \
35 tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \
36 tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \
37- tst-dlopenfail-2
38+ tst-dlopenfail-2 tst-tls21
39 # reldep9
40 tests-internal += loadtest unload unload2 circleload1 \
41 neededtest neededtest2 neededtest3 neededtest4 \
42@@ -312,7 +312,7 @@
43 tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9 \
44 tst-initlazyfailmod tst-finilazyfailmod \
45 tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \
46- tst-dlopenfailmod3 tst-ldconfig-ld-mod
47+ tst-dlopenfailmod3 tst-ldconfig-ld-mod tst-tls21mod
48 # Most modules build with _ISOMAC defined, but those filtered out
49 # depend on internal headers.
50 modules-names-tests = $(filter-out ifuncmod% tst-libc_dlvsym-dso tst-tlsmod%,\
51@@ -1697,5 +1697,10 @@
52 $(objpfx)tst-dlopen-nodelete-reloc-mod16.so
53 LDFLAGS-tst-dlopen-nodelete-reloc-mod17.so = -Wl,--no-as-needed
54
55+# Reuses tst-tls-many-dynamic-modules
56+$(objpfx)tst-tls21: $(libdl) $(shared-thread-library)
57+$(objpfx)tst-tls21.out: $(objpfx)tst-tls21mod.so
58+$(objpfx)tst-tls21mod.so: $(tst-tls-many-dynamic-modules:%=$(objpfx)%.so)
59+
60 $(objpfx)tst-ldconfig-ld_so_conf-update.out: $(objpfx)tst-ldconfig-ld-mod.so
61 $(objpfx)tst-ldconfig-ld_so_conf-update: $(libdl)
62diff --git a/elf/tst-tls21.c b/elf/tst-tls21.c
63new file mode 100644
64index 0000000000..560bf5813a
65--- /dev/null
66+++ b/elf/tst-tls21.c
67@@ -0,0 +1,68 @@
68+/* Test concurrent dlopen and pthread_create: BZ 19329.
69+ Copyright (C) 2021 Free Software Foundation, Inc.
70+ This file is part of the GNU C Library.
71+
72+ The GNU C Library is free software; you can redistribute it and/or
73+ modify it under the terms of the GNU Lesser General Public
74+ License as published by the Free Software Foundation; either
75+ version 2.1 of the License, or (at your option) any later version.
76+
77+ The GNU C Library is distributed in the hope that it will be useful,
78+ but WITHOUT ANY WARRANTY; without even the implied warranty of
79+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
80+ Lesser General Public License for more details.
81+
82+ You should have received a copy of the GNU Lesser General Public
83+ License along with the GNU C Library; if not, see
84+ <http://www.gnu.org/licenses/>. */
85+
86+#include <dlfcn.h>
87+#include <pthread.h>
88+#include <stdio.h>
89+#include <stdatomic.h>
90+#include <support/xdlfcn.h>
91+#include <support/xthread.h>
92+
93+#define THREADS 10000
94+
95+static atomic_int done;
96+
97+static void *
98+start (void *a)
99+{
100+ /* Load a module with many dependencies that each have TLS. */
101+ xdlopen ("tst-tls21mod.so", RTLD_LAZY);
102+ atomic_store_explicit (&done, 1, memory_order_release);
103+ return 0;
104+}
105+
106+static void *
107+nop (void *a)
108+{
109+ return 0;
110+}
111+
112+static int
113+do_test (void)
114+{
115+ pthread_t t1, t2;
116+ int i;
117+
118+ /* Load a module with lots of dependencies and TLS. */
119+ t1 = xpthread_create (0, start, 0);
120+
121+ /* Concurrently create lots of threads until dlopen is observably done. */
122+ for (i = 0; i < THREADS; i++)
123+ {
124+ if (atomic_load_explicit (&done, memory_order_acquire) != 0)
125+ break;
126+ t2 = xpthread_create (0, nop, 0);
127+ xpthread_join (t2);
128+ }
129+
130+ xpthread_join (t1);
131+ printf ("threads created during dlopen: %d\n", i);
132+ return 0;
133+}
134+
135+#include <support/test-driver.c>
136diff --git a/elf/tst-tls21mod.c b/elf/tst-tls21mod.c
137new file mode 100644
138index 0000000000..206ece4fb3
139--- /dev/null
140+++ b/elf/tst-tls21mod.c
141@@ -0,0 +1 @@
142+int __thread x;
143--
1442.27.0
diff --git a/meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch b/meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch
new file mode 100644
index 0000000000..a87afe3230
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0034-elf-Fix-DTV-gap-reuse-logic-BZ-27135.patch
@@ -0,0 +1,180 @@
1From ba33937be210da5d07f7f01709323743f66011ce Mon Sep 17 00:00:00 2001
2From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
3Date: Fri, 25 Jun 2021 10:54:12 -0300
4Subject: [PATCH] elf: Fix DTV gap reuse logic (BZ #27135)
5
6This is updated version of the 572bd547d57a (reverted by 40ebfd016ad2)
7that fixes the _dl_next_tls_modid issues.
8
9This issue with 572bd547d57a patch is the DTV entry will be only
10update on dl_open_worker() with the update_tls_slotinfo() call after
11all dependencies are being processed by _dl_map_object_deps(). However
12_dl_map_object_deps() itself might call _dl_next_tls_modid(), and since
13the _dl_tls_dtv_slotinfo_list::map is not yet set the entry will be
14wrongly reused.
15
16This patch fixes by renaming the _dl_next_tls_modid() function to
17_dl_assign_tls_modid() and by passing the link_map so it can set
18the slotinfo value so a subsequente _dl_next_tls_modid() call will
19see the entry as allocated.
20
21The intermediary value is cleared up on remove_slotinfo() for the case
22a library fails to load with RTLD_NOW.
23
24This patch fixes BZ #27135.
25
26Checked on x86_64-linux-gnu.
27
28Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
29---
30 elf/dl-close.c | 8 +-
31 elf/dl-load.c | 2 +-
32 elf/dl-open.c | 10 --
33 elf/dl-tls.c | 17 +--
34 elf/rtld.c | 2 +-
35 sysdeps/generic/ldsodefs.h | 4 +-
36 6 files changed, 349 insertions(+), 33 deletions(-)
37---
38Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=ba33937be210da5d07f7f01709323743f66011ce]
39Comment: Removed hunks those were related to test. Hunk from elf/rtld.c is refreshed.
40Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
41Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
42---
43diff --git a/elf/dl-close.c b/elf/dl-close.c
44index 3720e47dd1..f39001cab9 100644
45--- a/elf/dl-close.c
46+++ b/elf/dl-close.c
47@@ -77,8 +77,6 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
48 object that wasn't fully set up. */
49 if (__glibc_likely (old_map != NULL))
50 {
51- assert (old_map->l_tls_modid == idx);
52-
53 /* Mark the entry as unused. These can be read concurrently. */
54 atomic_store_relaxed (&listp->slotinfo[idx - disp].gen,
55 GL(dl_tls_generation) + 1);
56@@ -88,7 +86,11 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
57 /* If this is not the last currently used entry no need to look
58 further. */
59 if (idx != GL(dl_tls_max_dtv_idx))
60- return true;
61+ {
62+ /* There is an unused dtv entry in the middle. */
63+ GL(dl_tls_dtv_gaps) = true;
64+ return true;
65+ }
66 }
67
68 while (idx - disp > (disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0))
69diff --git a/elf/dl-load.c b/elf/dl-load.c
70index a08df001af..650e4edc35 100644
71--- a/elf/dl-load.c
72+++ b/elf/dl-load.c
73@@ -1498,7 +1498,7 @@ cannot enable executable stack as shared object requires");
74 not set up TLS data structures, so don't use them now. */
75 || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL)))
76 /* Assign the next available module ID. */
77- l->l_tls_modid = _dl_next_tls_modid ();
78+ _dl_assign_tls_modid (l);
79
80 #ifdef DL_AFTER_LOAD
81 DL_AFTER_LOAD (l);
82diff --git a/elf/dl-open.c b/elf/dl-open.c
83index a066f39bd0..d2240d8747 100644
84--- a/elf/dl-open.c
85+++ b/elf/dl-open.c
86@@ -899,16 +899,6 @@ no more namespaces available for dlmopen()"));
87 state if relocation failed, for example. */
88 if (args.map)
89 {
90- /* Maybe some of the modules which were loaded use TLS.
91- Since it will be removed in the following _dl_close call
92- we have to mark the dtv array as having gaps to fill the
93- holes. This is a pessimistic assumption which won't hurt
94- if not true. There is no need to do this when we are
95- loading the auditing DSOs since TLS has not yet been set
96- up. */
97- if ((mode & __RTLD_AUDIT) == 0)
98- GL(dl_tls_dtv_gaps) = true;
99-
100 _dl_close_worker (args.map, true);
101
102 /* All l_nodelete_pending objects should have been deleted
103diff --git a/elf/dl-tls.c b/elf/dl-tls.c
104index 2b5161d10a..423e380f7c 100644
105--- a/elf/dl-tls.c
106+++ b/elf/dl-tls.c
107@@ -126,8 +126,8 @@ oom (void)
108 }
109
110
111-size_t
112-_dl_next_tls_modid (void)
113+void
114+_dl_assign_tls_modid (struct link_map *l)
115 {
116 size_t result;
117
118@@ -157,7 +157,11 @@ _dl_next_tls_modid (void)
119 }
120
121 if (result - disp < runp->len)
122- break;
123+ {
124+ /* Mark the entry as used, so any dependency see it. */
125+ atomic_store_relaxed (&runp->slotinfo[result - disp].map, l);
126+ break;
127+ }
128
129 disp += runp->len;
130 }
131@@ -184,17 +188,14 @@ _dl_next_tls_modid (void)
132 atomic_store_relaxed (&GL(dl_tls_max_dtv_idx), result);
133 }
134
135- return result;
136+ l->l_tls_modid = result;
137 }
138
139
140 size_t
141 _dl_count_modids (void)
142 {
143- /* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where
144- we fail to load a module and unload it leaving a gap. If we don't
145- have gaps then the number of modids is the current maximum so
146- return that. */
147+ /* The count is the max unless dlclose or failed dlopen created gaps. */
148 if (__glibc_likely (!GL(dl_tls_dtv_gaps)))
149 return GL(dl_tls_max_dtv_idx);
150
151diff --git a/elf/rtld.c b/elf/rtld.c
152index e3fb2a5b2a..d733359eaf 100644
153--- a/elf/rtld.c
154+++ b/elf/rtld.c
155@@ -1612,7 +1612,7 @@
156 /* Add the dynamic linker to the TLS list if it also uses TLS. */
157 if (GL(dl_rtld_map).l_tls_blocksize != 0)
158 /* Assign a module ID. Do this before loading any audit modules. */
159- GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
160+ _dl_assign_tls_modid (&GL(dl_rtld_map));
161
162 /* If we have auditing DSOs to load, do it now. */
163 bool need_security_init = true;
164diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
165index 176394de4d..9c15259236 100644
166--- a/sysdeps/generic/ldsodefs.h
167+++ b/sysdeps/generic/ldsodefs.h
168@@ -1171,8 +1171,8 @@ extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
169 extern void _dl_sysdep_start_cleanup (void) attribute_hidden;
170
171
172-/* Determine next available module ID. */
173-extern size_t _dl_next_tls_modid (void) attribute_hidden;
174+/* Determine next available module ID and set the L l_tls_modid. */
175+extern void _dl_assign_tls_modid (struct link_map *l) attribute_hidden;
176
177 /* Count the modules with TLS segments. */
178 extern size_t _dl_count_modids (void) attribute_hidden;
179--
1802.27.0
diff --git a/meta/recipes-core/glibc/glibc/0035-x86_64-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch b/meta/recipes-core/glibc/glibc/0035-x86_64-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch
new file mode 100644
index 0000000000..899111b118
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0035-x86_64-Avoid-lazy-relocation-of-tlsdesc-BZ-27137.patch
@@ -0,0 +1,56 @@
1From 8f7e09f4dbdb5c815a18b8285fbc5d5d7bc17d86 Mon Sep 17 00:00:00 2001
2From: Szabolcs Nagy <szabolcs.nagy@arm.com>
3Date: Thu, 11 Feb 2021 11:29:23 +0000
4Subject: [PATCH] x86_64: Avoid lazy relocation of tlsdesc [BZ #27137]
5
6Lazy tlsdesc relocation is racy because the static tls optimization and
7tlsdesc management operations are done without holding the dlopen lock.
8
9This similar to the commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67
10for aarch64, but it fixes a different race: bug 27137.
11
12Another issue is that ld auditing ignores DT_BIND_NOW and thus tries to
13relocate tlsdesc lazily, but that does not work in a BIND_NOW module
14due to missing DT_TLSDESC_PLT. Unconditionally relocating tlsdesc at
15load time fixes this bug 27721 too.
16---
17 sysdeps/x86_64/dl-machine.h | 19 ++++++++++++++-----
18 1 file changed, 14 insertions(+), 5 deletions(-)
19---
20Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=8f7e09f4dbdb5c815a18b8285fbc5d5d7bc17d86]
21Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
22Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
23---
24diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
25index 103eee6c3f..9a876a371e 100644
26--- a/sysdeps/x86_64/dl-machine.h
27+++ b/sysdeps/x86_64/dl-machine.h
28@@ -570,12 +570,21 @@ elf_machine_lazy_rel (struct link_map *map,
29 }
30 else if (__glibc_likely (r_type == R_X86_64_TLSDESC))
31 {
32- struct tlsdesc volatile * __attribute__((__unused__)) td =
33- (struct tlsdesc volatile *)reloc_addr;
34+ const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
35+ const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]);
36+ const ElfW (Sym) *sym = &symtab[symndx];
37+ const struct r_found_version *version = NULL;
38
39- td->arg = (void*)reloc;
40- td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
41- + map->l_addr);
42+ if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
43+ {
44+ const ElfW (Half) *vernum =
45+ (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
46+ version = &map->l_versions[vernum[symndx] & 0x7fff];
47+ }
48+
49+ /* Always initialize TLS descriptors completely at load time, in
50+ case static TLS is allocated for it that requires locking. */
51+ elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
52 }
53 else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE))
54 {
55--
562.27.0
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 @@
1From ddcacd91cc10ff92d6201eda87047d029c14158d Mon Sep 17 00:00:00 2001
2From: Szabolcs Nagy <szabolcs.nagy@arm.com>
3Date: Thu, 11 Feb 2021 11:40:11 +0000
4Subject: [PATCH] i386: Avoid lazy relocation of tlsdesc [BZ #27137]
5
6Lazy tlsdesc relocation is racy because the static tls optimization and
7tlsdesc management operations are done without holding the dlopen lock.
8
9This similar to the commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67
10for aarch64, but it fixes a different race: bug 27137.
11
12On i386 the code is a bit more complicated than on x86_64 because both
13rel and rela relocs are supported.
14---
15 sysdeps/i386/dl-machine.h | 76 ++++++++++++++++++---------------------
16 1 file changed, 34 insertions(+), 42 deletions(-)
17---
18Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=ddcacd91cc10ff92d6201eda87047d029c14158d]
19Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
20Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
21---
22diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
23index 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--
1242.27.0
diff --git a/meta/recipes-core/glibc/glibc/0037-Avoid-deadlock-between-pthread_create-and-ctors.patch b/meta/recipes-core/glibc/glibc/0037-Avoid-deadlock-between-pthread_create-and-ctors.patch
new file mode 100644
index 0000000000..7a10131bad
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0037-Avoid-deadlock-between-pthread_create-and-ctors.patch
@@ -0,0 +1,276 @@
1From 83b5323261bb72313bffcf37476c1b8f0847c736 Mon Sep 17 00:00:00 2001
2From: Szabolcs Nagy <szabolcs.nagy@arm.com>
3Date: Wed, 15 Sep 2021 15:16:19 +0100
4Subject: [PATCH] elf: Avoid deadlock between pthread_create and ctors [BZ
5 #28357]
6
7The fix for bug 19329 caused a regression such that pthread_create can
8deadlock when concurrent ctors from dlopen are waiting for it to finish.
9Use a new GL(dl_load_tls_lock) in pthread_create that is not taken
10around ctors in dlopen.
11
12The new lock is also used in __tls_get_addr instead of GL(dl_load_lock).
13
14The new lock is held in _dl_open_worker and _dl_close_worker around
15most of the logic before/after the init/fini routines. When init/fini
16routines are running then TLS is in a consistent, usable state.
17In _dl_open_worker the new lock requires catching and reraising dlopen
18failures that happen in the critical section.
19
20The new lock is reinitialized in a fork child, to keep the existing
21behaviour and it is kept recursive in case malloc interposition or TLS
22access from signal handlers can retake it. It is not obvious if this
23is necessary or helps, but avoids changing the preexisting behaviour.
24
25The new lock may be more appropriate for dl_iterate_phdr too than
26GL(dl_load_write_lock), since TLS state of an incompletely loaded
27module may be accessed. If the new lock can replace the old one,
28that can be a separate change.
29
30Fixes bug 28357.
31
32Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
33---
34 elf/dl-close.c | 6 ++
35 elf/dl-open.c | 35 ++++++++-
36 elf/dl-support.c | 7 ++
37 elf/dl-tls.c | 16 ++---
38 elf/rtld.c | 1 +
39 sysdeps/nptl/fork.c | 3 +
40 sysdeps/generic/ldsodefs.h | 9 ++-
41 10 files changed, 235 insertions(+), 12 deletions(-)
42---
43Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=024a7640ab9ecea80e527f4e4d7f7a1868e952c5]
44Comment: This patch is refreshed for glibc 2.31. In upstream glibc 2.34 multiple src files are shuffled, updated this patch as per the code present in glibc 2.31. Removed test case.
45Signed-off-by: Akash Hadke <akash.hadke@kpit.com>
46Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
47---
48diff --git a/elf/dl-close.c b/elf/dl-close.c
49index 93ff5c96e9..cfe0f1c0c9 100644
50--- a/elf/dl-close.c
51+++ b/elf/dl-close.c
52@@ -551,6 +551,9 @@
53 size_t tls_free_end;
54 tls_free_start = tls_free_end = NO_TLS_OFFSET;
55
56+ /* Protects global and module specitic TLS state. */
57+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
58+
59 /* We modify the list of loaded objects. */
60 __rtld_lock_lock_recursive (GL(dl_load_write_lock));
61
62@@ -786,6 +789,9 @@
63 GL(dl_tls_static_used) = tls_free_start;
64 }
65
66+ /* TLS is cleaned up for the unloaded modules. */
67+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
68+
69 #ifdef SHARED
70 /* Auditing checkpoint: we have deleted all objects. */
71 if (__glibc_unlikely (do_audit))
72diff --git a/elf/dl-open.c b/elf/dl-open.c
73index 5295e931b0..6ea5dd2457 100644
74--- a/elf/dl-open.c
75+++ b/elf/dl-open.c
76@@ -57,6 +57,9 @@
77 (non-negative). */
78 unsigned int original_global_scope_pending_adds;
79
80+ /* Set to true if the end of dl_open_worker_begin was reached. */
81+ bool worker_continue;
82+
83 /* Original parameters to the program and the current environment. */
84 int argc;
85 char **argv;
86@@ -473,7 +473,7 @@
87 }
88
89 static void
90-dl_open_worker (void *a)
91+dl_open_worker_begin (void *a)
92 {
93 struct dl_open_args *args = a;
94 const char *file = args->file;
95@@ -747,6 +747,36 @@
96 if (mode & RTLD_GLOBAL)
97 add_to_global_resize (new);
98
99+ args->worker_continue = true;
100+}
101+
102+static void
103+dl_open_worker (void *a)
104+{
105+ struct dl_open_args *args = a;
106+
107+ args->worker_continue = false;
108+
109+ {
110+ /* Protects global and module specific TLS state. */
111+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
112+
113+ struct dl_exception ex;
114+ int err = _dl_catch_exception (&ex, dl_open_worker_begin, args);
115+
116+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
117+
118+ if (__glibc_unlikely (ex.errstring != NULL))
119+ /* Reraise the error. */
120+ _dl_signal_exception (err, &ex, NULL);
121+ }
122+
123+ if (!args->worker_continue)
124+ return;
125+
126+ int mode = args->mode;
127+ struct link_map *new = args->map;
128+
129 /* Run the initializer functions of new objects. Temporarily
130 disable the exception handler, so that lazy binding failures are
131 fatal. */
132diff --git a/elf/dl-support.c b/elf/dl-support.c
133index 02e2ed72f5..d99c1f1d62 100644
134--- a/elf/dl-support.c
135+++ b/elf/dl-support.c
136@@ -219,6 +219,13 @@
137 list of loaded objects while an object is added to or removed from
138 that list. */
139 __rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
140+/* This lock protects global and module specific TLS related data.
141+ E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
142+ GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
143+ accessed and when TLS related relocations are processed for a
144+ module. It was introduced to keep pthread_create accessing TLS
145+ state that is being set up. */
146+__rtld_lock_define_initialized_recursive (, _dl_load_tls_lock)
147
148
149 #ifdef HAVE_AUX_VECTOR
150diff --git a/elf/dl-tls.c b/elf/dl-tls.c
151index d554ae4497..9260d2d696 100644
152--- a/elf/dl-tls.c
153+++ b/elf/dl-tls.c
154@@ -443,7 +443,7 @@
155 size_t maxgen = 0;
156
157 /* Protects global dynamic TLS related state. */
158- __rtld_lock_lock_recursive (GL(dl_load_lock));
159+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
160
161 /* Check if the current dtv is big enough. */
162 if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
163@@ -517,7 +517,7 @@
164 listp = listp->next;
165 assert (listp != NULL);
166 }
167- __rtld_lock_unlock_recursive (GL(dl_load_lock));
168+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
169
170 /* The DTV version is up-to-date now. */
171 dtv[0].counter = maxgen;
172@@ -656,7 +656,7 @@
173
174 Here the dtv needs to be updated to new_gen generation count.
175
176- This code may be called during TLS access when GL(dl_load_lock)
177+ This code may be called during TLS access when GL(dl_load_tls_lock)
178 is not held. In that case the user code has to synchronize with
179 dlopen and dlclose calls of relevant modules. A module m is
180 relevant if the generation of m <= new_gen and dlclose of m is
181@@ -778,11 +778,11 @@
182 if (__glibc_unlikely (the_map->l_tls_offset
183 != FORCED_DYNAMIC_TLS_OFFSET))
184 {
185- __rtld_lock_lock_recursive (GL(dl_load_lock));
186+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
187 if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET))
188 {
189 the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET;
190- __rtld_lock_unlock_recursive (GL(dl_load_lock));
191+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
192 }
193 else if (__glibc_likely (the_map->l_tls_offset
194 != FORCED_DYNAMIC_TLS_OFFSET))
195@@ -794,7 +794,7 @@
196 #else
197 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
198 #endif
199- __rtld_lock_unlock_recursive (GL(dl_load_lock));
200+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
201
202 dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
203 dtv[GET_ADDR_MODULE].pointer.val = p;
204@@ -802,7 +802,7 @@
205 return (char *) p + GET_ADDR_OFFSET;
206 }
207 else
208- __rtld_lock_unlock_recursive (GL(dl_load_lock));
209+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
210 }
211 struct dtv_pointer result = allocate_and_init (the_map);
212 dtv[GET_ADDR_MODULE].pointer = result;
213@@ -873,7 +873,7 @@
214 return NULL;
215
216 dtv_t *dtv = THREAD_DTV ();
217- /* This may be called without holding the GL(dl_load_lock). Reading
218+ /* This may be called without holding the GL(dl_load_tls_lock). Reading
219 arbitrary gen value is fine since this is best effort code. */
220 size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
221 if (__glibc_unlikely (dtv[0].counter != gen))
222diff --git a/elf/rtld.c b/elf/rtld.c
223index 8d2bba3d43..9642eb9c92 100644
224--- a/elf/rtld.c
225+++ b/elf/rtld.c
226@@ -283,6 +283,7 @@
227 #ifdef _LIBC_REENTRANT
228 ._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
229 ._dl_load_write_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
230+ ._dl_load_tls_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
231 #endif
232 ._dl_nns = 1,
233 ._dl_ns =
234diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
235index c471f7b15f..021691b9b7 100644
236--- a/sysdeps/nptl/fork.c
237+++ b/sysdeps/nptl/fork.c
238@@ -125,6 +125,9 @@
239 /* Reset the lock the dynamic loader uses to protect its data. */
240 __rtld_lock_initialize (GL(dl_load_lock));
241
242+ /* Reset the lock protecting dynamic TLS related data. */
243+ __rtld_lock_initialize (GL(dl_load_tls_lock));
244+
245 /* Run the handlers registered for the child. */
246 __run_fork_handlers (atfork_run_child, multiple_threads);
247 }
248diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
249index d49529da0d..9ec1511bb0 100644
250--- a/sysdeps/generic/ldsodefs.h
251+++ b/sysdeps/generic/ldsodefs.h
252@@ -369,6 +369,13 @@
253 list of loaded objects while an object is added to or removed
254 from that list. */
255 __rtld_lock_define_recursive (EXTERN, _dl_load_write_lock)
256+ /* This lock protects global and module specific TLS related data.
257+ E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
258+ GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
259+ accessed and when TLS related relocations are processed for a
260+ module. It was introduced to keep pthread_create accessing TLS
261+ state that is being set up. */
262+ __rtld_lock_define_recursive (EXTERN, _dl_load_tls_lock)
263
264 /* Incremented whenever something may have been added to dl_loaded. */
265 EXTERN unsigned long long _dl_load_adds;
266@@ -1153,7 +1160,7 @@
267
268 /* Add module to slot information data. If DO_ADD is false, only the
269 required memory is allocated. Must be called with GL
270- (dl_load_lock) acquired. If the function has already been called
271+ (dl_load_tls_lock) acquired. If the function has already been called
272 for the link map L with !do_add, then this function will not raise
273 an exception, otherwise it is possible that it encounters a memory
274 allocation failure. */
275--
2762.27.0
diff --git a/meta/recipes-core/glibc/glibc/CVE-2019-25013.patch b/meta/recipes-core/glibc/glibc/CVE-2019-25013.patch
deleted file mode 100644
index 73df1da868..0000000000
--- a/meta/recipes-core/glibc/glibc/CVE-2019-25013.patch
+++ /dev/null
@@ -1,135 +0,0 @@
1From ee7a3144c9922808181009b7b3e50e852fb4999b Mon Sep 17 00:00:00 2001
2From: Andreas Schwab <schwab@suse.de>
3Date: Mon, 21 Dec 2020 08:56:43 +0530
4Subject: [PATCH] Fix buffer overrun in EUC-KR conversion module (bz #24973)
5
6The byte 0xfe as input to the EUC-KR conversion denotes a user-defined
7area and is not allowed. The from_euc_kr function used to skip two bytes
8when told to skip over the unknown designation, potentially running over
9the buffer end.
10
11Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=ee7a3144c9922808181009b7b3e50e852fb4999b]
12CVE: CVE-2019-25013
13Signed-off-by: Scott Murray <scott.murray@konsulko.com>
14[Refreshed for Dundell context; Makefile changes]
15Signed-off-by: Armin Kuster <akuster@mvista.com>
16
17---
18 iconvdata/Makefile | 3 ++-
19 iconvdata/bug-iconv13.c | 53 +++++++++++++++++++++++++++++++++++++++++
20 iconvdata/euc-kr.c | 6 +----
21 iconvdata/ksc5601.h | 6 ++---
22 4 files changed, 59 insertions(+), 9 deletions(-)
23 create mode 100644 iconvdata/bug-iconv13.c
24
25Index: git/iconvdata/Makefile
26===================================================================
27--- git.orig/iconvdata/Makefile
28+++ git/iconvdata/Makefile
29@@ -73,7 +73,7 @@ modules.so := $(addsuffix .so, $(modules
30 ifeq (yes,$(build-shared))
31 tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
32 tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
33- bug-iconv10 bug-iconv11 bug-iconv12
34+ bug-iconv10 bug-iconv11 bug-iconv12 bug-iconv13
35 ifeq ($(have-thread-library),yes)
36 tests += bug-iconv3
37 endif
38Index: git/iconvdata/bug-iconv13.c
39===================================================================
40--- /dev/null
41+++ git/iconvdata/bug-iconv13.c
42@@ -0,0 +1,53 @@
43+/* bug 24973: Test EUC-KR module
44+ Copyright (C) 2020 Free Software Foundation, Inc.
45+ This file is part of the GNU C Library.
46+
47+ The GNU C Library is free software; you can redistribute it and/or
48+ modify it under the terms of the GNU Lesser General Public
49+ License as published by the Free Software Foundation; either
50+ version 2.1 of the License, or (at your option) any later version.
51+
52+ The GNU C Library is distributed in the hope that it will be useful,
53+ but WITHOUT ANY WARRANTY; without even the implied warranty of
54+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
55+ Lesser General Public License for more details.
56+
57+ You should have received a copy of the GNU Lesser General Public
58+ License along with the GNU C Library; if not, see
59+ <https://www.gnu.org/licenses/>. */
60+
61+#include <errno.h>
62+#include <iconv.h>
63+#include <stdio.h>
64+#include <support/check.h>
65+
66+static int
67+do_test (void)
68+{
69+ iconv_t cd = iconv_open ("UTF-8//IGNORE", "EUC-KR");
70+ TEST_VERIFY_EXIT (cd != (iconv_t) -1);
71+
72+ /* 0xfe (->0x7e : row 94) and 0xc9 (->0x49 : row 41) are user-defined
73+ areas, which are not allowed and should be skipped over due to
74+ //IGNORE. The trailing 0xfe also is an incomplete sequence, which
75+ should be checked first. */
76+ char input[4] = { '\xc9', '\xa1', '\0', '\xfe' };
77+ char *inptr = input;
78+ size_t insize = sizeof (input);
79+ char output[4];
80+ char *outptr = output;
81+ size_t outsize = sizeof (output);
82+
83+ /* This used to crash due to buffer overrun. */
84+ TEST_VERIFY (iconv (cd, &inptr, &insize, &outptr, &outsize) == (size_t) -1);
85+ TEST_VERIFY (errno == EINVAL);
86+ /* The conversion should produce one character, the converted null
87+ character. */
88+ TEST_VERIFY (sizeof (output) - outsize == 1);
89+
90+ TEST_VERIFY_EXIT (iconv_close (cd) != -1);
91+
92+ return 0;
93+}
94+
95+#include <support/test-driver.c>
96Index: git/iconvdata/euc-kr.c
97===================================================================
98--- git.orig/iconvdata/euc-kr.c
99+++ git/iconvdata/euc-kr.c
100@@ -80,11 +80,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned c
101 \
102 if (ch <= 0x9f) \
103 ++inptr; \
104- /* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are \
105- user-defined areas. */ \
106- else if (__builtin_expect (ch == 0xa0, 0) \
107- || __builtin_expect (ch > 0xfe, 0) \
108- || __builtin_expect (ch == 0xc9, 0)) \
109+ else if (__glibc_unlikely (ch == 0xa0)) \
110 { \
111 /* This is illegal. */ \
112 STANDARD_FROM_LOOP_ERR_HANDLER (1); \
113Index: git/iconvdata/ksc5601.h
114===================================================================
115--- git.orig/iconvdata/ksc5601.h
116+++ git/iconvdata/ksc5601.h
117@@ -50,15 +50,15 @@ ksc5601_to_ucs4 (const unsigned char **s
118 unsigned char ch2;
119 int idx;
120
121+ if (avail < 2)
122+ return 0;
123+
124 /* row 94(0x7e) and row 41(0x49) are user-defined area in KS C 5601 */
125
126 if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) >= 0x7e
127 || (ch - offset) == 0x49)
128 return __UNKNOWN_10646_CHAR;
129
130- if (avail < 2)
131- return 0;
132-
133 ch2 = (*s)[1];
134 if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f)
135 return __UNKNOWN_10646_CHAR;
diff --git a/meta/recipes-core/glibc/glibc/CVE-2020-29562.patch b/meta/recipes-core/glibc/glibc/CVE-2020-29562.patch
deleted file mode 100644
index c51fb3223a..0000000000
--- a/meta/recipes-core/glibc/glibc/CVE-2020-29562.patch
+++ /dev/null
@@ -1,156 +0,0 @@
1From 228edd356f03bf62dcf2b1335f25d43c602ee68d Mon Sep 17 00:00:00 2001
2From: Michael Colavita <mcolavita@fb.com>
3Date: Thu, 19 Nov 2020 11:44:40 -0500
4Subject: [PATCH] iconv: Fix incorrect UCS4 inner loop bounds (BZ#26923)
5
6Previously, in UCS4 conversion routines we limit the number of
7characters we examine to the minimum of the number of characters in the
8input and the number of characters in the output. This is not the
9correct behavior when __GCONV_IGNORE_ERRORS is set, as we do not consume
10an output character when we skip a code unit. Instead, track the input
11and output pointers and terminate the loop when either reaches its
12limit.
13
14This resolves assertion failures when resetting the input buffer in a step of
15iconv, which assumes that the input will be fully consumed given sufficient
16output space.
17
18Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=commit;h=228edd356f03bf62dcf2b1335f25d43c602ee68d]
19CVE: CVE-2020-29562
20Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
21
22---
23 iconv/Makefile | 2 +-
24 iconv/gconv_simple.c | 16 ++++----------
25 iconv/tst-iconv8.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
26 3 files changed, 55 insertions(+), 13 deletions(-)
27 create mode 100644 iconv/tst-iconv8.c
28
29diff --git a/iconv/Makefile b/iconv/Makefile
30index 30bf996d3a..f9b51e23ec 100644
31--- a/iconv/Makefile
32+++ b/iconv/Makefile
33@@ -44,7 +44,7 @@ CFLAGS-linereader.c += -DNO_TRANSLITERATION
34 CFLAGS-simple-hash.c += -I../locale
35
36 tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 \
37- tst-iconv7 tst-iconv-mt tst-iconv-opt
38+ tst-iconv7 tst-iconv8 tst-iconv-mt tst-iconv-opt
39
40 others = iconv_prog iconvconfig
41 install-others-programs = $(inst_bindir)/iconv
42diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
43index d4797fba17..963b29f246 100644
44--- a/iconv/gconv_simple.c
45+++ b/iconv/gconv_simple.c
46@@ -239,11 +239,9 @@ ucs4_internal_loop (struct __gconv_step *step,
47 int flags = step_data->__flags;
48 const unsigned char *inptr = *inptrp;
49 unsigned char *outptr = *outptrp;
50- size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
51 int result;
52- size_t cnt;
53
54- for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
55+ for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
56 {
57 uint32_t inval;
58
59@@ -307,11 +305,9 @@ ucs4_internal_loop_unaligned (struct __gconv_step *step,
60 int flags = step_data->__flags;
61 const unsigned char *inptr = *inptrp;
62 unsigned char *outptr = *outptrp;
63- size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
64 int result;
65- size_t cnt;
66
67- for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
68+ for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
69 {
70 if (__glibc_unlikely (inptr[0] > 0x80))
71 {
72@@ -613,11 +609,9 @@ ucs4le_internal_loop (struct __gconv_step *step,
73 int flags = step_data->__flags;
74 const unsigned char *inptr = *inptrp;
75 unsigned char *outptr = *outptrp;
76- size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
77 int result;
78- size_t cnt;
79
80- for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
81+ for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
82 {
83 uint32_t inval;
84
85@@ -684,11 +678,9 @@ ucs4le_internal_loop_unaligned (struct __gconv_step *step,
86 int flags = step_data->__flags;
87 const unsigned char *inptr = *inptrp;
88 unsigned char *outptr = *outptrp;
89- size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
90 int result;
91- size_t cnt;
92
93- for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
94+ for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
95 {
96 if (__glibc_unlikely (inptr[3] > 0x80))
97 {
98diff --git a/iconv/tst-iconv8.c b/iconv/tst-iconv8.c
99new file mode 100644
100index 0000000000..0b92b19f66
101--- /dev/null
102+++ b/iconv/tst-iconv8.c
103@@ -0,0 +1,50 @@
104+/* Test iconv behavior on UCS4 conversions with //IGNORE.
105+ Copyright (C) 2020 Free Software Foundation, Inc.
106+ This file is part of the GNU C Library.
107+
108+ The GNU C Library is free software; you can redistribute it and/or
109+ modify it under the terms of the GNU Lesser General Public
110+ License as published by the Free Software Foundation; either
111+ version 2.1 of the License, or (at your option) any later version.
112+
113+ The GNU C Library is distributed in the hope that it will be useful,
114+ but WITHOUT ANY WARRANTY; without even the implied warranty of
115+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
116+ Lesser General Public License for more details.
117+
118+ You should have received a copy of the GNU Lesser General Public
119+ License along with the GNU C Library; if not, see
120+ <http://www.gnu.org/licenses/>. */
121+
122+/* Derived from BZ #26923 */
123+#include <errno.h>
124+#include <iconv.h>
125+#include <stdio.h>
126+#include <support/check.h>
127+
128+static int
129+do_test (void)
130+{
131+ iconv_t cd = iconv_open ("UTF-8//IGNORE", "ISO-10646/UCS4/");
132+ TEST_VERIFY_EXIT (cd != (iconv_t) -1);
133+
134+ /*
135+ * Convert sequence beginning with an irreversible character into buffer that
136+ * is too small.
137+ */
138+ char input[12] = "\xe1\x80\xa1" "AAAAAAAAA";
139+ char *inptr = input;
140+ size_t insize = sizeof (input);
141+ char output[6];
142+ char *outptr = output;
143+ size_t outsize = sizeof (output);
144+
145+ TEST_VERIFY (iconv (cd, &inptr, &insize, &outptr, &outsize) == -1);
146+ TEST_VERIFY (errno == E2BIG);
147+
148+ TEST_VERIFY_EXIT (iconv_close (cd) != -1);
149+
150+ return 0;
151+}
152+
153+#include <support/test-driver.c>
154--
1552.27.0
156
diff --git a/meta/recipes-core/glibc/glibc/CVE-2021-33574_1.patch b/meta/recipes-core/glibc/glibc/CVE-2021-33574_1.patch
new file mode 100644
index 0000000000..7561e87121
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2021-33574_1.patch
@@ -0,0 +1,68 @@
1From 42d359350510506b87101cf77202fefcbfc790cb Mon Sep 17 00:00:00 2001
2From: Andreas Schwab <schwab@linux-m68k.org>
3Date: Thu, 27 May 2021 12:49:47 +0200
4Subject: [PATCH] Use __pthread_attr_copy in mq_notify (bug 27896)
5
6Make a deep copy of the pthread attribute object to remove a potential
7use-after-free issue.
8
9Upstream-Status: Backport
10CVE: CVE-2021-33574 patch#1
11Signed-off-by: Armin Kuster <akuster@mvista.com>
12
13---
14diff --git a/NEWS b/NEWS
15index 8a20d3c4e3..be489243ac 100644
16--- a/NEWS
17+++ b/NEWS
18@@ -7,6 +7,10 @@ using `glibc' in the "product" field.
19
20 Version 2.31.1
21
22+ CVE-2021-33574: The mq_notify function has a potential use-after-free
23+ issue when using a notification type of SIGEV_THREAD and a thread
24+ attribute with a non-default affinity mask.
25+
26 The following bugs are resolved with this release:
27 [14231] stdio-common tests memory requirements
28 [19519] iconv(1) with -c option hangs on illegal multi-byte sequences
29diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c
30index f288bac477..dd47f0b777 100644
31--- a/sysdeps/unix/sysv/linux/mq_notify.c
32+++ b/sysdeps/unix/sysv/linux/mq_notify.c
33@@ -135,8 +135,11 @@ helper_thread (void *arg)
34 (void) __pthread_barrier_wait (&notify_barrier);
35 }
36 else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED)
37- /* The only state we keep is the copy of the thread attributes. */
38- free (data.attr);
39+ {
40+ /* The only state we keep is the copy of the thread attributes. */
41+ pthread_attr_destroy (data.attr);
42+ free (data.attr);
43+ }
44 }
45 return NULL;
46 }
47@@ -257,8 +260,7 @@ mq_notify (mqd_t mqdes, const struct sigevent *notification)
48 if (data.attr == NULL)
49 return -1;
50
51- memcpy (data.attr, notification->sigev_notify_attributes,
52- sizeof (pthread_attr_t));
53+ __pthread_attr_copy (data.attr, notification->sigev_notify_attributes);
54 }
55
56 /* Construct the new request. */
57@@ -272,7 +274,10 @@ mq_notify (mqd_t mqdes, const struct sigevent *notification)
58
59 /* If it failed, free the allocated memory. */
60 if (__glibc_unlikely (retval != 0))
61- free (data.attr);
62+ {
63+ pthread_attr_destroy (data.attr);
64+ free (data.attr);
65+ }
66
67 return retval;
68 }
diff --git a/meta/recipes-core/glibc/glibc/CVE-2021-33574_2.patch b/meta/recipes-core/glibc/glibc/CVE-2021-33574_2.patch
new file mode 100644
index 0000000000..396cd7fc0e
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2021-33574_2.patch
@@ -0,0 +1,73 @@
1From 217b6dc298156bdb0d6aea9ea93e7e394a5ff091 Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Tue, 1 Jun 2021 17:51:41 +0200
4Subject: [PATCH] Fix use of __pthread_attr_copy in mq_notify (bug 27896)
5
6__pthread_attr_copy can fail and does not initialize the attribute
7structure in that case.
8
9If __pthread_attr_copy is never called and there is no allocated
10attribute, pthread_attr_destroy should not be called, otherwise
11there is a null pointer dereference in rt/tst-mqueue6.
12
13Fixes commit 42d359350510506b87101cf77202fefcbfc790cb
14("Use __pthread_attr_copy in mq_notify (bug 27896)").
15
16Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
17
18https://sourceware.org/bugzilla/attachment.cgi?id=13497
19
20Upstream-Status: Backport
21CVE: CVE-2021-33574 patch#2
22Signed-off-by: Armin Kuster &lt;akuster@mvista.com&gt;
23
24---
25Index: git/sysdeps/unix/sysv/linux/mq_notify.c
26===================================================================
27--- git.orig/sysdeps/unix/sysv/linux/mq_notify.c
28+++ git/sysdeps/unix/sysv/linux/mq_notify.c
29@@ -260,7 +260,34 @@ mq_notify (mqd_t mqdes, const struct sig
30 if (data.attr == NULL)
31 return -1;
32
33- __pthread_attr_copy (data.attr, notification->sigev_notify_attributes);
34+ memcpy (data.attr, notification->sigev_notify_attributes,
35+ sizeof (pthread_attr_t));
36+
37+ struct pthread_attr *source =
38+ (struct pthread_attr *) (notification->sigev_notify_attributes);
39+ struct pthread_attr *target = (struct pthread_attr *) (data.attr);
40+ cpu_set_t *newp;
41+ cpu_set_t *cpuset = source->cpuset;
42+ size_t cpusetsize = source->cpusetsize;
43+
44+ /* alloc a new memory for cpuset to avoid use after free */
45+ if (cpuset != NULL && cpusetsize > 0)
46+ {
47+ newp = (cpu_set_t *) malloc (cpusetsize);
48+ if (newp == NULL)
49+ {
50+ free(data.attr);
51+ return -1;
52+ }
53+
54+ memcpy (newp, cpuset, cpusetsize);
55+ target->cpuset = newp;
56+ }
57+ else
58+ {
59+ target->cpuset = NULL;
60+ target->cpusetsize = 0;
61+ }
62 }
63
64 /* Construct the new request. */
65@@ -273,7 +300,7 @@ mq_notify (mqd_t mqdes, const struct sig
66 int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se);
67
68 /* If it failed, free the allocated memory. */
69- if (__glibc_unlikely (retval != 0))
70+ if (retval != 0 && data.attr != NULL)
71 {
72 pthread_attr_destroy (data.attr);
73 free (data.attr);
diff --git a/meta/recipes-core/glibc/glibc/CVE-2021-38604.patch b/meta/recipes-core/glibc/glibc/CVE-2021-38604.patch
new file mode 100644
index 0000000000..36fd4a61b2
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2021-38604.patch
@@ -0,0 +1,41 @@
1From b805aebd42364fe696e417808a700fdb9800c9e8 Mon Sep 17 00:00:00 2001
2From: Nikita Popov <npv1310@gmail.com>
3Date: Mon, 9 Aug 2021 20:17:34 +0530
4Subject: [PATCH] librt: fix NULL pointer dereference (bug 28213)
5
6Helper thread frees copied attribute on NOTIFY_REMOVED message
7received from the OS kernel. Unfortunately, it fails to check whether
8copied attribute actually exists (data.attr != NULL). This worked
9earlier because free() checks passed pointer before actually
10attempting to release corresponding memory. But
11__pthread_attr_destroy assumes pointer is not NULL.
12
13So passing NULL pointer to __pthread_attr_destroy will result in
14segmentation fault. This scenario is possible if
15notification->sigev_notify_attributes == NULL (which means default
16thread attributes should be used).
17
18Signed-off-by: Nikita Popov <npv1310@gmail.com>
19Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
20
21Upstream-Status: Backport
22CVE: CVE-2021-38604
23Signed-off-by: Armin Kuser <akuster@mvista.com>
24
25---
26 sysdeps/unix/sysv/linux/mq_notify.c | 2 +-
27 1 file changed, 1 insertion(+), 1 deletion(-)
28
29Index: git/sysdeps/unix/sysv/linux/mq_notify.c
30===================================================================
31--- git.orig/sysdeps/unix/sysv/linux/mq_notify.c
32+++ git/sysdeps/unix/sysv/linux/mq_notify.c
33@@ -134,7 +134,7 @@ helper_thread (void *arg)
34 to wait until it is done with it. */
35 (void) __pthread_barrier_wait (&notify_barrier);
36 }
37- else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED)
38+ else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED && data.attr != NULL)
39 {
40 /* The only state we keep is the copy of the thread attributes. */
41 pthread_attr_destroy (data.attr);
diff --git a/meta/recipes-core/glibc/glibc/CVE-2023-0687.patch b/meta/recipes-core/glibc/glibc/CVE-2023-0687.patch
new file mode 100644
index 0000000000..10c7e5666d
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2023-0687.patch
@@ -0,0 +1,82 @@
1From 952aff5c00ad7c6b83c3f310f2643939538827f8 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?=
3 =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= <leo@yuriev.ru>
4Date: Sat, 4 Feb 2023 14:41:38 +0300
5Subject: [PATCH] gmon: Fix allocated buffer overflow (bug 29444)
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10The `__monstartup()` allocates a buffer used to store all the data
11accumulated by the monitor.
12
13The size of this buffer depends on the size of the internal structures
14used and the address range for which the monitor is activated, as well
15as on the maximum density of call instructions and/or callable functions
16that could be potentially on a segment of executable code.
17
18In particular a hash table of arcs is placed at the end of this buffer.
19The size of this hash table is calculated in bytes as
20 p->fromssize = p->textsize / HASHFRACTION;
21
22but actually should be
23 p->fromssize = ROUNDUP(p->textsize / HASHFRACTION, sizeof(*p->froms));
24
25This results in writing beyond the end of the allocated buffer when an
26added arc corresponds to a call near from the end of the monitored
27address range, since `_mcount()` check the incoming caller address for
28monitored range but not the intermediate result hash-like index that
29uses to write into the table.
30
31It should be noted that when the results are output to `gmon.out`, the
32table is read to the last element calculated from the allocated size in
33bytes, so the arcs stored outside the buffer boundary did not fall into
34`gprof` for analysis. Thus this "feature" help me to found this bug
35during working with https://sourceware.org/bugzilla/show_bug.cgi?id=29438
36
37Just in case, I will explicitly note that the problem breaks the
38`make test t=gmon/tst-gmon-dso` added for Bug 29438.
39There, the arc of the `f3()` call disappears from the output, since in
40the DSO case, the call to `f3` is located close to the end of the
41monitored range.
42
43Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
44
45Another minor error seems a related typo in the calculation of
46`kcountsize`, but since kcounts are smaller than froms, this is
47actually to align the p->froms data.
48
49Co-authored-by: DJ Delorie <dj@redhat.com>
50Reviewed-by: Carlos O'Donell <carlos@redhat.com>
51
52Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=commit;h=801af9fafd4689337ebf27260aa115335a0cb2bc]
53CVE: CVE-2023-0687
54Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
55---
56 gmon/gmon.c | 4 +++-
57 1 file changed, 3 insertions(+), 1 deletion(-)
58
59diff --git a/gmon/gmon.c b/gmon/gmon.c
60index dee6480..bf76358 100644
61--- a/gmon/gmon.c
62+++ b/gmon/gmon.c
63@@ -132,6 +132,8 @@ __monstartup (u_long lowpc, u_long highpc)
64 p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
65 p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
66 p->textsize = p->highpc - p->lowpc;
67+ /* This looks like a typo, but it's here to align the p->froms
68+ section. */
69 p->kcountsize = ROUNDUP(p->textsize / HISTFRACTION, sizeof(*p->froms));
70 p->hashfraction = HASHFRACTION;
71 p->log_hashfraction = -1;
72@@ -142,7 +144,7 @@ __monstartup (u_long lowpc, u_long highpc)
73 instead of integer division. Precompute shift amount. */
74 p->log_hashfraction = ffs(p->hashfraction * sizeof(*p->froms)) - 1;
75 }
76- p->fromssize = p->textsize / HASHFRACTION;
77+ p->fromssize = ROUNDUP(p->textsize / HASHFRACTION, sizeof(*p->froms));
78 p->tolimit = p->textsize * ARCDENSITY / 100;
79 if (p->tolimit < MINARCS)
80 p->tolimit = MINARCS;
81--
822.7.4
diff --git a/meta/recipes-core/glibc/glibc/CVE-2023-4813.patch b/meta/recipes-core/glibc/glibc/CVE-2023-4813.patch
new file mode 100644
index 0000000000..c7db4038c2
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2023-4813.patch
@@ -0,0 +1,986 @@
1From 1c37b8022e8763fedbb3f79c02e05c6acfe5a215 Mon Sep 17 00:00:00 2001
2From: Siddhesh Poyarekar <siddhesh@sourceware.org>
3Date: Thu, 17 Mar 2022 11:44:34 +0530
4Subject: [PATCH] Simplify allocations and fix merge and continue actions [BZ
5 #28931]
6
7Allocations for address tuples is currently a bit confusing because of
8the pointer chasing through PAT, making it hard to observe the sequence
9in which allocations have been made. Narrow scope of the pointer
10chasing through PAT so that it is only used where necessary.
11
12This also tightens actions behaviour with the hosts database in
13getaddrinfo to comply with the manual text. The "continue" action
14discards previous results and the "merge" action results in an immedate
15lookup failure. Consequently, chaining of allocations across modules is
16no longer necessary, thus opening up cleanup opportunities.
17
18A test has been added that checks some combinations to ensure that they
19work correctly.
20
21Resolves: BZ #28931
22
23CVE: CVE-2023-4813
24Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=1c37b8022e8763fedbb3f79c02e05c6acfe5a215]
25Comments: Hunks refreshed
26
27Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
28Reviewed-by: DJ Delorie <dj@redhat.com>
29Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
30---
31 nss/Makefile | 1 +
32 nss/tst-nss-gai-actions.c | 149 ++++++
33 nss/tst-nss-gai-actions.root/etc/host.conf | 1 +
34 nss/tst-nss-gai-actions.root/etc/hosts | 508 +++++++++++++++++++++
35 sysdeps/posix/getaddrinfo.c | 143 +++---
36 5 files changed, 750 insertions(+), 52 deletions(-)
37 create mode 100644 nss/tst-nss-gai-actions.c
38 create mode 100644 nss/tst-nss-gai-actions.root/etc/host.conf
39 create mode 100644 nss/tst-nss-gai-actions.root/etc/hosts
40
41diff --git a/nss/Makefile b/nss/Makefile
42index 42a59535cb..d8b06b44fb 100644
43--- a/nss/Makefile
44+++ b/nss/Makefile
45@@ -61,6 +61,7 @@
46
47 tests-container = \
48 tst-nss-test3 \
49+ tst-nss-gai-actions \
50 tst-nss-files-hosts-long \
51 tst-nss-db-endpwent \
52 tst-nss-db-endgrent
53diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c
54new file mode 100644
55index 0000000000..efca6cd183
56--- /dev/null
57+++ b/nss/tst-nss-gai-actions.c
58@@ -0,0 +1,149 @@
59+/* Test continue and merge NSS actions for getaddrinfo.
60+ Copyright The GNU Toolchain Authors.
61+ This file is part of the GNU C Library.
62+
63+ The GNU C Library is free software; you can redistribute it and/or
64+ modify it under the terms of the GNU Lesser General Public
65+ License as published by the Free Software Foundation; either
66+ version 2.1 of the License, or (at your option) any later version.
67+
68+ The GNU C Library is distributed in the hope that it will be useful,
69+ but WITHOUT ANY WARRANTY; without even the implied warranty of
70+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
71+ Lesser General Public License for more details.
72+
73+ You should have received a copy of the GNU Lesser General Public
74+ License along with the GNU C Library; if not, see
75+ <https://www.gnu.org/licenses/>. */
76+
77+#include <dlfcn.h>
78+#include <gnu/lib-names.h>
79+#include <nss.h>
80+#include <stdio.h>
81+#include <stdlib.h>
82+#include <string.h>
83+
84+#include <support/check.h>
85+#include <support/format_nss.h>
86+#include <support/support.h>
87+#include <support/xstdio.h>
88+#include <support/xunistd.h>
89+
90+enum
91+{
92+ ACTION_MERGE = 0,
93+ ACTION_CONTINUE,
94+};
95+
96+static const char *
97+family_str (int family)
98+{
99+ switch (family)
100+ {
101+ case AF_UNSPEC:
102+ return "AF_UNSPEC";
103+ case AF_INET:
104+ return "AF_INET";
105+ default:
106+ __builtin_unreachable ();
107+ }
108+}
109+
110+static const char *
111+action_str (int action)
112+{
113+ switch (action)
114+ {
115+ case ACTION_MERGE:
116+ return "merge";
117+ case ACTION_CONTINUE:
118+ return "continue";
119+ default:
120+ __builtin_unreachable ();
121+ }
122+}
123+
124+static void
125+do_one_test (int action, int family, bool canon)
126+{
127+ struct addrinfo hints =
128+ {
129+ .ai_family = family,
130+ };
131+
132+ struct addrinfo *ai;
133+
134+ if (canon)
135+ hints.ai_flags = AI_CANONNAME;
136+
137+ printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n",
138+ action_str (action), family_str (family),
139+ canon ? "AI_CANONNAME" : "");
140+
141+ int ret = getaddrinfo ("example.org", "80", &hints, &ai);
142+
143+ switch (action)
144+ {
145+ case ACTION_MERGE:
146+ if (ret == 0)
147+ {
148+ char *formatted = support_format_addrinfo (ai, ret);
149+
150+ printf ("merge unexpectedly succeeded:\n %s\n", formatted);
151+ support_record_failure ();
152+ free (formatted);
153+ }
154+ else
155+ return;
156+ case ACTION_CONTINUE:
157+ {
158+ char *formatted = support_format_addrinfo (ai, ret);
159+
160+ /* Verify that the result appears exactly once. */
161+ const char *expected = "address: STREAM/TCP 192.0.0.1 80\n"
162+ "address: DGRAM/UDP 192.0.0.1 80\n"
163+ "address: RAW/IP 192.0.0.1 80\n";
164+
165+ const char *contains = strstr (formatted, expected);
166+ const char *contains2 = NULL;
167+
168+ if (contains != NULL)
169+ contains2 = strstr (contains + strlen (expected), expected);
170+
171+ if (contains == NULL || contains2 != NULL)
172+ {
173+ printf ("continue failed:\n%s\n", formatted);
174+ support_record_failure ();
175+ }
176+
177+ free (formatted);
178+ break;
179+ }
180+ default:
181+ __builtin_unreachable ();
182+ }
183+}
184+
185+static void
186+do_one_test_set (int action)
187+{
188+ char buf[32];
189+
190+ snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files",
191+ action_str (action));
192+ __nss_configure_lookup ("hosts", buf);
193+
194+ do_one_test (action, AF_UNSPEC, false);
195+ do_one_test (action, AF_INET, false);
196+ do_one_test (action, AF_INET, true);
197+}
198+
199+static int
200+do_test (void)
201+{
202+ do_one_test_set (ACTION_CONTINUE);
203+ do_one_test_set (ACTION_MERGE);
204+ return 0;
205+}
206+
207+#include <support/test-driver.c>
208diff --git a/nss/tst-nss-gai-actions.root/etc/host.conf b/nss/tst-nss-gai-actions.root/etc/host.conf
209new file mode 100644
210index 0000000000..d1a59f73a9
211--- /dev/null
212+++ b/nss/tst-nss-gai-actions.root/etc/host.conf
213@@ -0,0 +1 @@
214+multi on
215diff --git a/nss/tst-nss-gai-actions.root/etc/hosts b/nss/tst-nss-gai-actions.root/etc/hosts
216new file mode 100644
217index 0000000000..50ce9774dc
218--- /dev/null
219+++ b/nss/tst-nss-gai-actions.root/etc/hosts
220@@ -0,0 +1,508 @@
221+192.0.0.1 example.org
222+192.0.0.2 example.org
223+192.0.0.3 example.org
224+192.0.0.4 example.org
225+192.0.0.5 example.org
226+192.0.0.6 example.org
227+192.0.0.7 example.org
228+192.0.0.8 example.org
229+192.0.0.9 example.org
230+192.0.0.10 example.org
231+192.0.0.11 example.org
232+192.0.0.12 example.org
233+192.0.0.13 example.org
234+192.0.0.14 example.org
235+192.0.0.15 example.org
236+192.0.0.16 example.org
237+192.0.0.17 example.org
238+192.0.0.18 example.org
239+192.0.0.19 example.org
240+192.0.0.20 example.org
241+192.0.0.21 example.org
242+192.0.0.22 example.org
243+192.0.0.23 example.org
244+192.0.0.24 example.org
245+192.0.0.25 example.org
246+192.0.0.26 example.org
247+192.0.0.27 example.org
248+192.0.0.28 example.org
249+192.0.0.29 example.org
250+192.0.0.30 example.org
251+192.0.0.31 example.org
252+192.0.0.32 example.org
253+192.0.0.33 example.org
254+192.0.0.34 example.org
255+192.0.0.35 example.org
256+192.0.0.36 example.org
257+192.0.0.37 example.org
258+192.0.0.38 example.org
259+192.0.0.39 example.org
260+192.0.0.40 example.org
261+192.0.0.41 example.org
262+192.0.0.42 example.org
263+192.0.0.43 example.org
264+192.0.0.44 example.org
265+192.0.0.45 example.org
266+192.0.0.46 example.org
267+192.0.0.47 example.org
268+192.0.0.48 example.org
269+192.0.0.49 example.org
270+192.0.0.50 example.org
271+192.0.0.51 example.org
272+192.0.0.52 example.org
273+192.0.0.53 example.org
274+192.0.0.54 example.org
275+192.0.0.55 example.org
276+192.0.0.56 example.org
277+192.0.0.57 example.org
278+192.0.0.58 example.org
279+192.0.0.59 example.org
280+192.0.0.60 example.org
281+192.0.0.61 example.org
282+192.0.0.62 example.org
283+192.0.0.63 example.org
284+192.0.0.64 example.org
285+192.0.0.65 example.org
286+192.0.0.66 example.org
287+192.0.0.67 example.org
288+192.0.0.68 example.org
289+192.0.0.69 example.org
290+192.0.0.70 example.org
291+192.0.0.71 example.org
292+192.0.0.72 example.org
293+192.0.0.73 example.org
294+192.0.0.74 example.org
295+192.0.0.75 example.org
296+192.0.0.76 example.org
297+192.0.0.77 example.org
298+192.0.0.78 example.org
299+192.0.0.79 example.org
300+192.0.0.80 example.org
301+192.0.0.81 example.org
302+192.0.0.82 example.org
303+192.0.0.83 example.org
304+192.0.0.84 example.org
305+192.0.0.85 example.org
306+192.0.0.86 example.org
307+192.0.0.87 example.org
308+192.0.0.88 example.org
309+192.0.0.89 example.org
310+192.0.0.90 example.org
311+192.0.0.91 example.org
312+192.0.0.92 example.org
313+192.0.0.93 example.org
314+192.0.0.94 example.org
315+192.0.0.95 example.org
316+192.0.0.96 example.org
317+192.0.0.97 example.org
318+192.0.0.98 example.org
319+192.0.0.99 example.org
320+192.0.0.100 example.org
321+192.0.0.101 example.org
322+192.0.0.102 example.org
323+192.0.0.103 example.org
324+192.0.0.104 example.org
325+192.0.0.105 example.org
326+192.0.0.106 example.org
327+192.0.0.107 example.org
328+192.0.0.108 example.org
329+192.0.0.109 example.org
330+192.0.0.110 example.org
331+192.0.0.111 example.org
332+192.0.0.112 example.org
333+192.0.0.113 example.org
334+192.0.0.114 example.org
335+192.0.0.115 example.org
336+192.0.0.116 example.org
337+192.0.0.117 example.org
338+192.0.0.118 example.org
339+192.0.0.119 example.org
340+192.0.0.120 example.org
341+192.0.0.121 example.org
342+192.0.0.122 example.org
343+192.0.0.123 example.org
344+192.0.0.124 example.org
345+192.0.0.125 example.org
346+192.0.0.126 example.org
347+192.0.0.127 example.org
348+192.0.0.128 example.org
349+192.0.0.129 example.org
350+192.0.0.130 example.org
351+192.0.0.131 example.org
352+192.0.0.132 example.org
353+192.0.0.133 example.org
354+192.0.0.134 example.org
355+192.0.0.135 example.org
356+192.0.0.136 example.org
357+192.0.0.137 example.org
358+192.0.0.138 example.org
359+192.0.0.139 example.org
360+192.0.0.140 example.org
361+192.0.0.141 example.org
362+192.0.0.142 example.org
363+192.0.0.143 example.org
364+192.0.0.144 example.org
365+192.0.0.145 example.org
366+192.0.0.146 example.org
367+192.0.0.147 example.org
368+192.0.0.148 example.org
369+192.0.0.149 example.org
370+192.0.0.150 example.org
371+192.0.0.151 example.org
372+192.0.0.152 example.org
373+192.0.0.153 example.org
374+192.0.0.154 example.org
375+192.0.0.155 example.org
376+192.0.0.156 example.org
377+192.0.0.157 example.org
378+192.0.0.158 example.org
379+192.0.0.159 example.org
380+192.0.0.160 example.org
381+192.0.0.161 example.org
382+192.0.0.162 example.org
383+192.0.0.163 example.org
384+192.0.0.164 example.org
385+192.0.0.165 example.org
386+192.0.0.166 example.org
387+192.0.0.167 example.org
388+192.0.0.168 example.org
389+192.0.0.169 example.org
390+192.0.0.170 example.org
391+192.0.0.171 example.org
392+192.0.0.172 example.org
393+192.0.0.173 example.org
394+192.0.0.174 example.org
395+192.0.0.175 example.org
396+192.0.0.176 example.org
397+192.0.0.177 example.org
398+192.0.0.178 example.org
399+192.0.0.179 example.org
400+192.0.0.180 example.org
401+192.0.0.181 example.org
402+192.0.0.182 example.org
403+192.0.0.183 example.org
404+192.0.0.184 example.org
405+192.0.0.185 example.org
406+192.0.0.186 example.org
407+192.0.0.187 example.org
408+192.0.0.188 example.org
409+192.0.0.189 example.org
410+192.0.0.190 example.org
411+192.0.0.191 example.org
412+192.0.0.192 example.org
413+192.0.0.193 example.org
414+192.0.0.194 example.org
415+192.0.0.195 example.org
416+192.0.0.196 example.org
417+192.0.0.197 example.org
418+192.0.0.198 example.org
419+192.0.0.199 example.org
420+192.0.0.200 example.org
421+192.0.0.201 example.org
422+192.0.0.202 example.org
423+192.0.0.203 example.org
424+192.0.0.204 example.org
425+192.0.0.205 example.org
426+192.0.0.206 example.org
427+192.0.0.207 example.org
428+192.0.0.208 example.org
429+192.0.0.209 example.org
430+192.0.0.210 example.org
431+192.0.0.211 example.org
432+192.0.0.212 example.org
433+192.0.0.213 example.org
434+192.0.0.214 example.org
435+192.0.0.215 example.org
436+192.0.0.216 example.org
437+192.0.0.217 example.org
438+192.0.0.218 example.org
439+192.0.0.219 example.org
440+192.0.0.220 example.org
441+192.0.0.221 example.org
442+192.0.0.222 example.org
443+192.0.0.223 example.org
444+192.0.0.224 example.org
445+192.0.0.225 example.org
446+192.0.0.226 example.org
447+192.0.0.227 example.org
448+192.0.0.228 example.org
449+192.0.0.229 example.org
450+192.0.0.230 example.org
451+192.0.0.231 example.org
452+192.0.0.232 example.org
453+192.0.0.233 example.org
454+192.0.0.234 example.org
455+192.0.0.235 example.org
456+192.0.0.236 example.org
457+192.0.0.237 example.org
458+192.0.0.238 example.org
459+192.0.0.239 example.org
460+192.0.0.240 example.org
461+192.0.0.241 example.org
462+192.0.0.242 example.org
463+192.0.0.243 example.org
464+192.0.0.244 example.org
465+192.0.0.245 example.org
466+192.0.0.246 example.org
467+192.0.0.247 example.org
468+192.0.0.248 example.org
469+192.0.0.249 example.org
470+192.0.0.250 example.org
471+192.0.0.251 example.org
472+192.0.0.252 example.org
473+192.0.0.253 example.org
474+192.0.0.254 example.org
475+192.0.1.1 example.org
476+192.0.1.2 example.org
477+192.0.1.3 example.org
478+192.0.1.4 example.org
479+192.0.1.5 example.org
480+192.0.1.6 example.org
481+192.0.1.7 example.org
482+192.0.1.8 example.org
483+192.0.1.9 example.org
484+192.0.1.10 example.org
485+192.0.1.11 example.org
486+192.0.1.12 example.org
487+192.0.1.13 example.org
488+192.0.1.14 example.org
489+192.0.1.15 example.org
490+192.0.1.16 example.org
491+192.0.1.17 example.org
492+192.0.1.18 example.org
493+192.0.1.19 example.org
494+192.0.1.20 example.org
495+192.0.1.21 example.org
496+192.0.1.22 example.org
497+192.0.1.23 example.org
498+192.0.1.24 example.org
499+192.0.1.25 example.org
500+192.0.1.26 example.org
501+192.0.1.27 example.org
502+192.0.1.28 example.org
503+192.0.1.29 example.org
504+192.0.1.30 example.org
505+192.0.1.31 example.org
506+192.0.1.32 example.org
507+192.0.1.33 example.org
508+192.0.1.34 example.org
509+192.0.1.35 example.org
510+192.0.1.36 example.org
511+192.0.1.37 example.org
512+192.0.1.38 example.org
513+192.0.1.39 example.org
514+192.0.1.40 example.org
515+192.0.1.41 example.org
516+192.0.1.42 example.org
517+192.0.1.43 example.org
518+192.0.1.44 example.org
519+192.0.1.45 example.org
520+192.0.1.46 example.org
521+192.0.1.47 example.org
522+192.0.1.48 example.org
523+192.0.1.49 example.org
524+192.0.1.50 example.org
525+192.0.1.51 example.org
526+192.0.1.52 example.org
527+192.0.1.53 example.org
528+192.0.1.54 example.org
529+192.0.1.55 example.org
530+192.0.1.56 example.org
531+192.0.1.57 example.org
532+192.0.1.58 example.org
533+192.0.1.59 example.org
534+192.0.1.60 example.org
535+192.0.1.61 example.org
536+192.0.1.62 example.org
537+192.0.1.63 example.org
538+192.0.1.64 example.org
539+192.0.1.65 example.org
540+192.0.1.66 example.org
541+192.0.1.67 example.org
542+192.0.1.68 example.org
543+192.0.1.69 example.org
544+192.0.1.70 example.org
545+192.0.1.71 example.org
546+192.0.1.72 example.org
547+192.0.1.73 example.org
548+192.0.1.74 example.org
549+192.0.1.75 example.org
550+192.0.1.76 example.org
551+192.0.1.77 example.org
552+192.0.1.78 example.org
553+192.0.1.79 example.org
554+192.0.1.80 example.org
555+192.0.1.81 example.org
556+192.0.1.82 example.org
557+192.0.1.83 example.org
558+192.0.1.84 example.org
559+192.0.1.85 example.org
560+192.0.1.86 example.org
561+192.0.1.87 example.org
562+192.0.1.88 example.org
563+192.0.1.89 example.org
564+192.0.1.90 example.org
565+192.0.1.91 example.org
566+192.0.1.92 example.org
567+192.0.1.93 example.org
568+192.0.1.94 example.org
569+192.0.1.95 example.org
570+192.0.1.96 example.org
571+192.0.1.97 example.org
572+192.0.1.98 example.org
573+192.0.1.99 example.org
574+192.0.1.100 example.org
575+192.0.1.101 example.org
576+192.0.1.102 example.org
577+192.0.1.103 example.org
578+192.0.1.104 example.org
579+192.0.1.105 example.org
580+192.0.1.106 example.org
581+192.0.1.107 example.org
582+192.0.1.108 example.org
583+192.0.1.109 example.org
584+192.0.1.110 example.org
585+192.0.1.111 example.org
586+192.0.1.112 example.org
587+192.0.1.113 example.org
588+192.0.1.114 example.org
589+192.0.1.115 example.org
590+192.0.1.116 example.org
591+192.0.1.117 example.org
592+192.0.1.118 example.org
593+192.0.1.119 example.org
594+192.0.1.120 example.org
595+192.0.1.121 example.org
596+192.0.1.122 example.org
597+192.0.1.123 example.org
598+192.0.1.124 example.org
599+192.0.1.125 example.org
600+192.0.1.126 example.org
601+192.0.1.127 example.org
602+192.0.1.128 example.org
603+192.0.1.129 example.org
604+192.0.1.130 example.org
605+192.0.1.131 example.org
606+192.0.1.132 example.org
607+192.0.1.133 example.org
608+192.0.1.134 example.org
609+192.0.1.135 example.org
610+192.0.1.136 example.org
611+192.0.1.137 example.org
612+192.0.1.138 example.org
613+192.0.1.139 example.org
614+192.0.1.140 example.org
615+192.0.1.141 example.org
616+192.0.1.142 example.org
617+192.0.1.143 example.org
618+192.0.1.144 example.org
619+192.0.1.145 example.org
620+192.0.1.146 example.org
621+192.0.1.147 example.org
622+192.0.1.148 example.org
623+192.0.1.149 example.org
624+192.0.1.150 example.org
625+192.0.1.151 example.org
626+192.0.1.152 example.org
627+192.0.1.153 example.org
628+192.0.1.154 example.org
629+192.0.1.155 example.org
630+192.0.1.156 example.org
631+192.0.1.157 example.org
632+192.0.1.158 example.org
633+192.0.1.159 example.org
634+192.0.1.160 example.org
635+192.0.1.161 example.org
636+192.0.1.162 example.org
637+192.0.1.163 example.org
638+192.0.1.164 example.org
639+192.0.1.165 example.org
640+192.0.1.166 example.org
641+192.0.1.167 example.org
642+192.0.1.168 example.org
643+192.0.1.169 example.org
644+192.0.1.170 example.org
645+192.0.1.171 example.org
646+192.0.1.172 example.org
647+192.0.1.173 example.org
648+192.0.1.174 example.org
649+192.0.1.175 example.org
650+192.0.1.176 example.org
651+192.0.1.177 example.org
652+192.0.1.178 example.org
653+192.0.1.179 example.org
654+192.0.1.180 example.org
655+192.0.1.181 example.org
656+192.0.1.182 example.org
657+192.0.1.183 example.org
658+192.0.1.184 example.org
659+192.0.1.185 example.org
660+192.0.1.186 example.org
661+192.0.1.187 example.org
662+192.0.1.188 example.org
663+192.0.1.189 example.org
664+192.0.1.190 example.org
665+192.0.1.191 example.org
666+192.0.1.192 example.org
667+192.0.1.193 example.org
668+192.0.1.194 example.org
669+192.0.1.195 example.org
670+192.0.1.196 example.org
671+192.0.1.197 example.org
672+192.0.1.198 example.org
673+192.0.1.199 example.org
674+192.0.1.200 example.org
675+192.0.1.201 example.org
676+192.0.1.202 example.org
677+192.0.1.203 example.org
678+192.0.1.204 example.org
679+192.0.1.205 example.org
680+192.0.1.206 example.org
681+192.0.1.207 example.org
682+192.0.1.208 example.org
683+192.0.1.209 example.org
684+192.0.1.210 example.org
685+192.0.1.211 example.org
686+192.0.1.212 example.org
687+192.0.1.213 example.org
688+192.0.1.214 example.org
689+192.0.1.215 example.org
690+192.0.1.216 example.org
691+192.0.1.217 example.org
692+192.0.1.218 example.org
693+192.0.1.219 example.org
694+192.0.1.220 example.org
695+192.0.1.221 example.org
696+192.0.1.222 example.org
697+192.0.1.223 example.org
698+192.0.1.224 example.org
699+192.0.1.225 example.org
700+192.0.1.226 example.org
701+192.0.1.227 example.org
702+192.0.1.228 example.org
703+192.0.1.229 example.org
704+192.0.1.230 example.org
705+192.0.1.231 example.org
706+192.0.1.232 example.org
707+192.0.1.233 example.org
708+192.0.1.234 example.org
709+192.0.1.235 example.org
710+192.0.1.236 example.org
711+192.0.1.237 example.org
712+192.0.1.238 example.org
713+192.0.1.239 example.org
714+192.0.1.240 example.org
715+192.0.1.241 example.org
716+192.0.1.242 example.org
717+192.0.1.243 example.org
718+192.0.1.244 example.org
719+192.0.1.245 example.org
720+192.0.1.246 example.org
721+192.0.1.247 example.org
722+192.0.1.248 example.org
723+192.0.1.249 example.org
724+192.0.1.250 example.org
725+192.0.1.251 example.org
726+192.0.1.252 example.org
727+192.0.1.253 example.org
728+192.0.1.254 example.org
729diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
730index 18dccd5924..3d9bea60c6 100644
731--- a/sysdeps/posix/getaddrinfo.c
732+++ b/sysdeps/posix/getaddrinfo.c
733@@ -458,11 +458,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
734
735 if (name != NULL)
736 {
737- at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
738- at->family = AF_UNSPEC;
739- at->scopeid = 0;
740- at->next = NULL;
741-
742 if (req->ai_flags & AI_IDN)
743 {
744 char *out;
745@@ -473,13 +468,21 @@ gaih_inet (const char *name, const struct gaih_service *service,
746 malloc_name = true;
747 }
748
749- if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
750+ uint32_t addr[4];
751+ if (__inet_aton_exact (name, (struct in_addr *) addr) != 0)
752 {
753+ at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
754+ at->scopeid = 0;
755+ at->next = NULL;
756+
757 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
758- at->family = AF_INET;
759+ {
760+ memcpy (at->addr, addr, sizeof (at->addr));
761+ at->family = AF_INET;
762+ }
763 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
764 {
765- at->addr[3] = at->addr[0];
766+ at->addr[3] = addr[0];
767 at->addr[2] = htonl (0xffff);
768 at->addr[1] = 0;
769 at->addr[0] = 0;
770@@ -505,49 +505,62 @@
771
772 if (req->ai_flags & AI_CANONNAME)
773 canon = name;
774+
775+ goto process_list;
776 }
777- else if (at->family == AF_UNSPEC)
778+
779+ char *scope_delim = strchr (name, SCOPE_DELIMITER);
780+ int e;
781+
782+ if (scope_delim == NULL)
783+ e = inet_pton (AF_INET6, name, addr);
784+ else
785+ e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr);
786+
787+ if (e > 0)
788 {
789- char *scope_delim = strchr (name, SCOPE_DELIMITER);
790- int e;
791- if (scope_delim == NULL)
792- e = inet_pton (AF_INET6, name, at->addr);
793+ at = alloca_account (sizeof (struct gaih_addrtuple),
794+ alloca_used);
795+ at->scopeid = 0;
796+ at->next = NULL;
797+
798+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
799+ {
800+ memcpy (at->addr, addr, sizeof (at->addr));
801+ at->family = AF_INET6;
802+ }
803+ else if (req->ai_family == AF_INET
804+ && IN6_IS_ADDR_V4MAPPED (addr))
805+ {
806+ at->addr[0] = addr[3];
807+ at->addr[1] = addr[1];
808+ at->addr[2] = addr[2];
809+ at->addr[3] = addr[3];
810+ at->family = AF_INET;
811+ }
812 else
813- e = __inet_pton_length (AF_INET6, name, scope_delim - name,
814- at->addr);
815- if (e > 0)
816 {
817- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
818- at->family = AF_INET6;
819- else if (req->ai_family == AF_INET
820- && IN6_IS_ADDR_V4MAPPED (at->addr))
821- {
822- at->addr[0] = at->addr[3];
823- at->family = AF_INET;
824- }
825- else
826- {
827- result = -EAI_ADDRFAMILY;
828- goto free_and_return;
829- }
830-
831- if (scope_delim != NULL
832- && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
833- scope_delim + 1,
834- &at->scopeid) != 0)
835- {
836- result = -EAI_NONAME;
837- goto free_and_return;
838- }
839+ result = -EAI_ADDRFAMILY;
840+ goto free_and_return;
841+ }
842
843- if (req->ai_flags & AI_CANONNAME)
844- canon = name;
845+ if (scope_delim != NULL
846+ && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
847+ scope_delim + 1,
848+ &at->scopeid) != 0)
849+ {
850+ result = -EAI_NONAME;
851+ goto free_and_return;
852 }
853+
854+ if (req->ai_flags & AI_CANONNAME)
855+ canon = name;
856+
857+ goto process_list;
858 }
859
860- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
861+ if ((req->ai_flags & AI_NUMERICHOST) == 0)
862 {
863- struct gaih_addrtuple **pat = &at;
864 int no_data = 0;
865 int no_inet6_data = 0;
866 service_user *nip;
867@@ -543,6 +559,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
868 enum nss_status status = NSS_STATUS_UNAVAIL;
869 int no_more;
870 struct resolv_context *res_ctx = NULL;
871+ bool do_merge = false;
872
873 /* If we do not have to look for IPv6 addresses or the canonical
874 name, use the simple, old functions, which do not support
875@@ -579,7 +596,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
876 result = -EAI_MEMORY;
877 goto free_and_return;
878 }
879- *pat = addrmem;
880+ at = addrmem;
881 }
882 else
883 {
884@@ -632,6 +649,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
885 }
886
887 struct gaih_addrtuple *addrfree = addrmem;
888+ struct gaih_addrtuple **pat = &at;
889+
890 for (int i = 0; i < air->naddrs; ++i)
891 {
892 socklen_t size = (air->family[i] == AF_INET
893@@ -695,12 +714,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
894
895 free (air);
896
897- if (at->family == AF_UNSPEC)
898- {
899- result = -EAI_NONAME;
900- goto free_and_return;
901- }
902-
903 goto process_list;
904 }
905 else if (err == 0)
906@@ -750,6 +763,22 @@
907
908 while (!no_more)
909 {
910+ /* Always start afresh; continue should discard previous results
911+ and the hosts database does not support merge. */
912+ at = NULL;
913+ free (canonbuf);
914+ free (addrmem);
915+ canon = canonbuf = NULL;
916+ addrmem = NULL;
917+ got_ipv6 = false;
918+
919+ if (do_merge)
920+ {
921+ __set_h_errno (NETDB_INTERNAL);
922+ __set_errno (EBUSY);
923+ break;
924+ }
925+
926 no_data = 0;
927 nss_gethostbyname4_r fct4 = NULL;
928
929@@ -744,12 +773,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
930 {
931 while (1)
932 {
933- status = DL_CALL_FCT (fct4, (name, pat,
934+ status = DL_CALL_FCT (fct4, (name, &at,
935 tmpbuf->data, tmpbuf->length,
936 &errno, &h_errno,
937 NULL));
938 if (status == NSS_STATUS_SUCCESS)
939 break;
940+ /* gethostbyname4_r may write into AT, so reset it. */
941+ at = NULL;
942 if (status != NSS_STATUS_TRYAGAIN
943 || errno != ERANGE || h_errno != NETDB_INTERNAL)
944 {
945@@ -774,7 +805,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
946 no_data = 1;
947
948 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
949- canon = (*pat)->name;
950+ canon = at->name;
951+
952+ struct gaih_addrtuple **pat = &at;
953
954 while (*pat != NULL)
955 {
956@@ -826,6 +859,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
957
958 if (fct != NULL)
959 {
960+ struct gaih_addrtuple **pat = &at;
961+
962 if (req->ai_family == AF_INET6
963 || req->ai_family == AF_UNSPEC)
964 {
965@@ -917,6 +946,10 @@
966 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
967 break;
968
969+ /* The hosts database does not support MERGE. */
970+ if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
971+ do_merge = true;
972+
973 if (nip->next == NULL)
974 no_more = -1;
975 else
976@@ -930,7 +969,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
977 }
978
979 process_list:
980- if (at->family == AF_UNSPEC)
981+ if (at == NULL)
982 {
983 result = -EAI_NONAME;
984 goto free_and_return;
985--
9862.39.3
diff --git a/meta/recipes-core/glibc/glibc/CVE-2023-4911.patch b/meta/recipes-core/glibc/glibc/CVE-2023-4911.patch
new file mode 100644
index 0000000000..4d3146509a
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2023-4911.patch
@@ -0,0 +1,63 @@
1From d2b77337f734fcacdfc8e0ddec14cf31a746c7be Mon Sep 17 00:00:00 2001
2From: Siddhesh Poyarekar <siddhesh@redhat.com>
3Date: Mon, 11 Sep 2023 18:53:15 -0400
4Subject: [PATCH v2] tunables: Terminate immediately if end of input is reached
5
6The string parsing routine may end up writing beyond bounds of tunestr
7if the input tunable string is malformed, of the form name=name=val.
8This gets processed twice, first as name=name=val and next as name=val,
9resulting in tunestr being name=name=val:name=val, thus overflowing
10tunestr.
11
12Terminate the parsing loop at the first instance itself so that tunestr
13does not overflow.
14---
15Changes from v1:
16
17- Also null-terminate tunestr before exiting.
18
19 elf/dl-tunables.c | 17 ++++++++++-------
20 1 file changed, 10 insertions(+), 7 deletions(-)
21
22Upstream-Status: Backport [git://sourceware.org/git/glibc.git]
23CVE: CVE-2023-4911
24
25diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
26index 8e7ee9df10..76cf8b9da3 100644
27--- a/elf/dl-tunables.c
28+++ b/elf/dl-tunables.c
29@@ -187,11 +187,7 @@ parse_tunables (char *tunestr, char *valstring)
30 /* If we reach the end of the string before getting a valid name-value
31 pair, bail out. */
32 if (p[len] == '\0')
33- {
34- if (__libc_enable_secure)
35- tunestr[off] = '\0';
36- return;
37- }
38+ break;
39
40 /* We did not find a valid name-value pair before encountering the
41 colon. */
42@@ -251,9 +247,16 @@ parse_tunables (char *tunestr, char *valstring)
43 }
44 }
45
46- if (p[len] != '\0')
47- p += len + 1;
48+ /* We reached the end while processing the tunable string. */
49+ if (p[len] == '\0')
50+ break;
51+
52+ p += len + 1;
53 }
54+
55+ /* Terminate tunestr before we leave. */
56+ if (__libc_enable_secure)
57+ tunestr[off] = '\0';
58 }
59 #endif
60
61--
622.41.0
63
diff --git a/meta/recipes-core/glibc/glibc/check-test-wrapper b/meta/recipes-core/glibc/glibc/check-test-wrapper
index f8e04e02d2..5cc993f718 100644
--- a/meta/recipes-core/glibc/glibc/check-test-wrapper
+++ b/meta/recipes-core/glibc/glibc/check-test-wrapper
@@ -2,6 +2,7 @@
2import sys 2import sys
3import os 3import os
4import subprocess 4import subprocess
5import resource
5 6
6env = os.environ.copy() 7env = os.environ.copy()
7args = sys.argv[1:] 8args = sys.argv[1:]
@@ -44,12 +45,20 @@ if targettype == "user":
44 qemuargs += ["-L", sysroot] 45 qemuargs += ["-L", sysroot]
45 qemuargs += ["-E", "LD_LIBRARY_PATH={}".format(":".join(libpaths))] 46 qemuargs += ["-E", "LD_LIBRARY_PATH={}".format(":".join(libpaths))]
46 command = qemuargs + args 47 command = qemuargs + args
48
49 # We've seen qemu-arm using up all system memory for some glibc
50 # tests e.g. nptl/tst-pthread-timedlock-lockloop
51 # Cap at 8GB since no test should need more than that
52 # (5GB adds 7 failures for qemuarm glibc test run)
53 limit = 8*1024*1024*1024
54 resource.setrlimit(resource.RLIMIT_AS, (limit, limit))
55
47elif targettype == "ssh": 56elif targettype == "ssh":
48 host = os.environ.get("SSH_HOST", None) 57 host = os.environ.get("SSH_HOST", None)
49 user = os.environ.get("SSH_HOST_USER", None) 58 user = os.environ.get("SSH_HOST_USER", None)
50 port = os.environ.get("SSH_HOST_PORT", None) 59 port = os.environ.get("SSH_HOST_PORT", None)
51 60
52 command = ["ssh", "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no"] 61 command = ["ssh", "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-o", "LogLevel=quiet"]
53 if port: 62 if port:
54 command += ["-p", str(port)] 63 command += ["-p", str(port)]
55 if not host: 64 if not host: