forgejo-lts: 7.0.10 -> 7.0.11
[NixPkgs.git] / pkgs / development / libraries / glibc / 2.40-master.patch
blob0b418d1dbeb3747fe14741b9b805680cd37a5035
1 commit 6daa77104520ca992a9369bd01cccd4d98c82984
2 Author: Andreas K. Hüttel <dilfridge@gentoo.org>
3 Date: Sun Jul 21 19:02:10 2024 +0200
5 Replace advisories directory
7 Signed-off-by: Andreas K. Hüttel <dilfridge@gentoo.org>
9 diff --git a/advisories/GLIBC-SA-2023-0001 b/advisories/GLIBC-SA-2023-0001
10 deleted file mode 100644
11 index 3d19c91b6a..0000000000
12 --- a/advisories/GLIBC-SA-2023-0001
13 +++ /dev/null
14 @@ -1,14 +0,0 @@
15 -printf: incorrect output for integers with thousands separator and width field
17 -When the printf family of functions is called with a format specifier
18 -that uses an <apostrophe> (enable grouping) and a minimum width
19 -specifier, the resulting output could be larger than reasonably expected
20 -by a caller that computed a tight bound on the buffer size. The
21 -resulting larger than expected output could result in a buffer overflow
22 -in the printf family of functions.
24 -CVE-Id: CVE-2023-25139
25 -Public-Date: 2023-02-02
26 -Vulnerable-Commit: e88b9f0e5cc50cab57a299dc7efe1a4eb385161d (2.37)
27 -Fix-Commit: c980549cc6a1c03c23cc2fe3e7b0fe626a0364b0 (2.38)
28 -Fix-Commit: 07b9521fc6369d000216b96562ff7c0ed32a16c4 (2.37-4)
29 diff --git a/advisories/GLIBC-SA-2023-0002 b/advisories/GLIBC-SA-2023-0002
30 deleted file mode 100644
31 index 5122669a64..0000000000
32 --- a/advisories/GLIBC-SA-2023-0002
33 +++ /dev/null
34 @@ -1,15 +0,0 @@
35 -getaddrinfo: Stack read overflow in no-aaaa mode
37 -If the system is configured in no-aaaa mode via /etc/resolv.conf,
38 -getaddrinfo is called for the AF_UNSPEC address family, and a DNS
39 -response is received over TCP that is larger than 2048 bytes,
40 -getaddrinfo may potentially disclose stack contents via the returned
41 -address data, or crash.
43 -CVE-Id: CVE-2023-4527
44 -Public-Date: 2023-09-12
45 -Vulnerable-Commit: f282cdbe7f436c75864e5640a409a10485e9abb2 (2.36)
46 -Fix-Commit: bd77dd7e73e3530203be1c52c8a29d08270cb25d (2.39)
47 -Fix-Commit: 4ea972b7edd7e36610e8cde18bf7a8149d7bac4f (2.36-113)
48 -Fix-Commit: b7529346025a130fee483d42178b5c118da971bb (2.37-38)
49 -Fix-Commit: b25508dd774b617f99419bdc3cf2ace4560cd2d6 (2.38-19)
50 diff --git a/advisories/GLIBC-SA-2023-0003 b/advisories/GLIBC-SA-2023-0003
51 deleted file mode 100644
52 index d3aef80348..0000000000
53 --- a/advisories/GLIBC-SA-2023-0003
54 +++ /dev/null
55 @@ -1,15 +0,0 @@
56 -getaddrinfo: Potential use-after-free
58 -When an NSS plugin only implements the _gethostbyname2_r and
59 -_getcanonname_r callbacks, getaddrinfo could use memory that was freed
60 -during buffer resizing, potentially causing a crash or read or write to
61 -arbitrary memory.
63 -CVE-Id: CVE-2023-4806
64 -Public-Date: 2023-09-12
65 -Fix-Commit: 973fe93a5675c42798b2161c6f29c01b0e243994 (2.39)
66 -Fix-Commit: e09ee267c03e3150c2c9ba28625ab130705a485e (2.34-420)
67 -Fix-Commit: e3ccb230a961b4797510e6a1f5f21fd9021853e7 (2.35-270)
68 -Fix-Commit: a9728f798ec7f05454c95637ee6581afaa9b487d (2.36-115)
69 -Fix-Commit: 6529a7466c935f36e9006b854d6f4e1d4876f942 (2.37-39)
70 -Fix-Commit: 00ae4f10b504bc4564e9f22f00907093f1ab9338 (2.38-20)
71 diff --git a/advisories/GLIBC-SA-2023-0004 b/advisories/GLIBC-SA-2023-0004
72 deleted file mode 100644
73 index 5286a7aa54..0000000000
74 --- a/advisories/GLIBC-SA-2023-0004
75 +++ /dev/null
76 @@ -1,16 +0,0 @@
77 -tunables: local privilege escalation through buffer overflow
79 -If a tunable of the form NAME=NAME=VAL is passed in the environment of a
80 -setuid program and NAME is valid, it may result in a buffer overflow,
81 -which could be exploited to achieve escalated privileges. This flaw was
82 -introduced in glibc 2.34.
84 -CVE-Id: CVE-2023-4911
85 -Public-Date: 2023-10-03
86 -Vulnerable-Commit: 2ed18c5b534d9e92fc006202a5af0df6b72e7aca (2.34)
87 -Fix-Commit: 1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa (2.39)
88 -Fix-Commit: dcc367f148bc92e7f3778a125f7a416b093964d9 (2.34-423)
89 -Fix-Commit: c84018a05aec80f5ee6f682db0da1130b0196aef (2.35-274)
90 -Fix-Commit: 22955ad85186ee05834e47e665056148ca07699c (2.36-118)
91 -Fix-Commit: b4e23c75aea756b4bddc4abcf27a1c6dca8b6bd3 (2.37-45)
92 -Fix-Commit: 750a45a783906a19591fb8ff6b7841470f1f5701 (2.38-27)
93 diff --git a/advisories/GLIBC-SA-2023-0005 b/advisories/GLIBC-SA-2023-0005
94 deleted file mode 100644
95 index cc4eb90b82..0000000000
96 --- a/advisories/GLIBC-SA-2023-0005
97 +++ /dev/null
98 @@ -1,18 +0,0 @@
99 -getaddrinfo: DoS due to memory leak
101 -The fix for CVE-2023-4806 introduced a memory leak when an application
102 -calls getaddrinfo for AF_INET6 with AI_CANONNAME, AI_ALL and AI_V4MAPPED
103 -flags set.
105 -CVE-Id: CVE-2023-5156
106 -Public-Date: 2023-09-25
107 -Vulnerable-Commit: e09ee267c03e3150c2c9ba28625ab130705a485e (2.34-420)
108 -Vulnerable-Commit: e3ccb230a961b4797510e6a1f5f21fd9021853e7 (2.35-270)
109 -Vulnerable-Commit: a9728f798ec7f05454c95637ee6581afaa9b487d (2.36-115)
110 -Vulnerable-Commit: 6529a7466c935f36e9006b854d6f4e1d4876f942 (2.37-39)
111 -Vulnerable-Commit: 00ae4f10b504bc4564e9f22f00907093f1ab9338 (2.38-20)
112 -Fix-Commit: 8006457ab7e1cd556b919f477348a96fe88f2e49 (2.34-421)
113 -Fix-Commit: 17092c0311f954e6f3c010f73ce3a78c24ac279a (2.35-272)
114 -Fix-Commit: 856bac55f98dc840e7c27cfa82262b933385de90 (2.36-116)
115 -Fix-Commit: 4473d1b87d04b25cdd0e0354814eeaa421328268 (2.37-42)
116 -Fix-Commit: 5ee59ca371b99984232d7584fe2b1a758b4421d3 (2.38-24)
117 diff --git a/advisories/GLIBC-SA-2024-0001 b/advisories/GLIBC-SA-2024-0001
118 deleted file mode 100644
119 index 28931c75ae..0000000000
120 --- a/advisories/GLIBC-SA-2024-0001
121 +++ /dev/null
122 @@ -1,15 +0,0 @@
123 -syslog: Heap buffer overflow in __vsyslog_internal
125 -__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER
126 -containing a long program name failed to update the required buffer
127 -size, leading to the allocation and overflow of a too-small buffer on
128 -the heap.
130 -CVE-Id: CVE-2023-6246
131 -Public-Date: 2024-01-30
132 -Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
133 -Fix-Commit: 6bd0e4efcc78f3c0115e5ea9739a1642807450da (2.39)
134 -Fix-Commit: 23514c72b780f3da097ecf33a793b7ba9c2070d2 (2.38-42)
135 -Fix-Commit: 97a4292aa4a2642e251472b878d0ec4c46a0e59a (2.37-57)
136 -Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
137 -Fix-Commit: d1a83b6767f68b3cb5b4b4ea2617254acd040c82 (2.36-126)
138 diff --git a/advisories/GLIBC-SA-2024-0002 b/advisories/GLIBC-SA-2024-0002
139 deleted file mode 100644
140 index 940bfcf2fc..0000000000
141 --- a/advisories/GLIBC-SA-2024-0002
142 +++ /dev/null
143 @@ -1,15 +0,0 @@
144 -syslog: Heap buffer overflow in __vsyslog_internal
146 -__vsyslog_internal used the return value of snprintf/vsnprintf to
147 -calculate buffer sizes for memory allocation. If these functions (for
148 -any reason) failed and returned -1, the resulting buffer would be too
149 -small to hold output.
151 -CVE-Id: CVE-2023-6779
152 -Public-Date: 2024-01-30
153 -Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
154 -Fix-Commit: 7e5a0c286da33159d47d0122007aac016f3e02cd (2.39)
155 -Fix-Commit: d0338312aace5bbfef85e03055e1212dd0e49578 (2.38-43)
156 -Fix-Commit: 67062eccd9a65d7fda9976a56aeaaf6c25a80214 (2.37-58)
157 -Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
158 -Fix-Commit: 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 (2.36-127)
159 diff --git a/advisories/GLIBC-SA-2024-0003 b/advisories/GLIBC-SA-2024-0003
160 deleted file mode 100644
161 index b43a5150ab..0000000000
162 --- a/advisories/GLIBC-SA-2024-0003
163 +++ /dev/null
164 @@ -1,13 +0,0 @@
165 -syslog: Integer overflow in __vsyslog_internal
167 -__vsyslog_internal calculated a buffer size by adding two integers, but
168 -did not first check if the addition would overflow.
170 -CVE-Id: CVE-2023-6780
171 -Public-Date: 2024-01-30
172 -Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
173 -Fix-Commit: ddf542da94caf97ff43cc2875c88749880b7259b (2.39)
174 -Fix-Commit: d37c2b20a4787463d192b32041c3406c2bd91de0 (2.38-44)
175 -Fix-Commit: 2b58cba076e912961ceaa5fa58588e4b10f791c0 (2.37-59)
176 -Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
177 -Fix-Commit: b9b7d6a27aa0632f334352fa400771115b3c69b7 (2.36-128)
178 diff --git a/advisories/GLIBC-SA-2024-0004 b/advisories/GLIBC-SA-2024-0004
179 deleted file mode 100644
180 index 08df2b3118..0000000000
181 --- a/advisories/GLIBC-SA-2024-0004
182 +++ /dev/null
183 @@ -1,28 +0,0 @@
184 -ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence
186 -The iconv() function in the GNU C Library versions 2.39 and older may
187 -overflow the output buffer passed to it by up to 4 bytes when converting
188 -strings to the ISO-2022-CN-EXT character set, which may be used to
189 -crash an application or overwrite a neighbouring variable.
191 -ISO-2022-CN-EXT uses escape sequences to indicate character set changes
192 -(as specified by RFC 1922). While the SOdesignation has the expected
193 -bounds checks, neither SS2designation nor SS3designation have its;
194 -allowing a write overflow of 1, 2, or 3 bytes with fixed values:
195 -'$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'.
197 -CVE-Id: CVE-2024-2961
198 -Public-Date: 2024-04-17
199 -Vulnerable-Commit: 755104edc75c53f4a0e7440334e944ad3c6b32fc (2.1.93-169)
200 -Fix-Commit: f9dc609e06b1136bb0408be9605ce7973a767ada (2.40)
201 -Fix-Commit: 31da30f23cddd36db29d5b6a1c7619361b271fb4 (2.39-31)
202 -Fix-Commit: e1135387deded5d73924f6ca20c72a35dc8e1bda (2.38-66)
203 -Fix-Commit: 89ce64b269a897a7780e4c73a7412016381c6ecf (2.37-89)
204 -Fix-Commit: 4ed98540a7fd19f458287e783ae59c41e64df7b5 (2.36-164)
205 -Fix-Commit: 36280d1ce5e245aabefb877fe4d3c6cff95dabfa (2.35-315)
206 -Fix-Commit: a8b0561db4b9847ebfbfec20075697d5492a363c (2.34-459)
207 -Fix-Commit: ed4f16ff6bed3037266f1fa682ebd32a18fce29c (2.33-263)
208 -Fix-Commit: 682ad4c8623e611a971839990ceef00346289cc9 (2.32-140)
209 -Fix-Commit: 3703c32a8d304c1ee12126134ce69be965f38000 (2.31-154)
211 -Reported-By: Charles Fol
212 diff --git a/advisories/GLIBC-SA-2024-0005 b/advisories/GLIBC-SA-2024-0005
213 deleted file mode 100644
214 index a59596610a..0000000000
215 --- a/advisories/GLIBC-SA-2024-0005
216 +++ /dev/null
217 @@ -1,22 +0,0 @@
218 -nscd: Stack-based buffer overflow in netgroup cache
220 -If the Name Service Cache Daemon's (nscd) fixed size cache is exhausted
221 -by client requests then a subsequent client request for netgroup data
222 -may result in a stack-based buffer overflow. This flaw was introduced
223 -in glibc 2.15 when the cache was added to nscd.
225 -This vulnerability is only present in the nscd binary.
227 -CVE-Id: CVE-2024-33599
228 -Public-Date: 2024-04-23
229 -Vulnerable-Commit: 684ae515993269277448150a1ca70db3b94aa5bd (2.15)
230 -Fix-Commit: 69c58d5ef9f584ea198bd00f7964d364d0e6b921 (2.31-155)
231 -Fix-Commit: a77064893bfe8a701770e2f53a4d33805bc47a5a (2.32-141)
232 -Fix-Commit: 5c75001a96abcd50cbdb74df24c3f013188d076e (2.33-264)
233 -Fix-Commit: 52f73e5c4e29b14e79167272297977f360ae1e97 (2.34-460)
234 -Fix-Commit: 7a95873543ce225376faf13bb71c43dea6d24f86 (2.35-316)
235 -Fix-Commit: caa3151ca460bdd9330adeedd68c3112d97bffe4 (2.36-165)
236 -Fix-Commit: f75c298e747b2b8b41b1c2f551c011a52c41bfd1 (2.37-91)
237 -Fix-Commit: 5968aebb86164034b8f8421b4abab2f837a5bdaf (2.38-72)
238 -Fix-Commit: 1263d583d2e28afb8be53f8d6922f0842036f35d (2.39-35)
239 -Fix-Commit: 87801a8fd06db1d654eea3e4f7626ff476a9bdaa (2.40)
240 diff --git a/advisories/GLIBC-SA-2024-0006 b/advisories/GLIBC-SA-2024-0006
241 deleted file mode 100644
242 index d44148d3d9..0000000000
243 --- a/advisories/GLIBC-SA-2024-0006
244 +++ /dev/null
245 @@ -1,32 +0,0 @@
246 -nscd: Null pointer crash after notfound response
248 -If the Name Service Cache Daemon's (nscd) cache fails to add a not-found
249 -netgroup response to the cache, the client request can result in a null
250 -pointer dereference. This flaw was introduced in glibc 2.15 when the
251 -cache was added to nscd.
253 -This vulnerability is only present in the nscd binary.
255 -CVE-Id: CVE-2024-33600
256 -Public-Date: 2024-04-24
257 -Vulnerable-Commit: 684ae515993269277448150a1ca70db3b94aa5bd (2.15)
258 -Fix-Commit: b048a482f088e53144d26a61c390bed0210f49f2 (2.40)
259 -Fix-Commit: 7835b00dbce53c3c87bbbb1754a95fb5e58187aa (2.40)
260 -Fix-Commit: c99f886de54446cd4447db6b44be93dabbdc2f8b (2.39-37)
261 -Fix-Commit: 5a508e0b508c8ad53bd0d2fb48fd71b242626341 (2.39-36)
262 -Fix-Commit: 2ae9446c1b7a3064743b4a51c0bbae668ee43e4c (2.38-74)
263 -Fix-Commit: 541ea5172aa658c4bd5c6c6d6fd13903c3d5bb0a (2.38-73)
264 -Fix-Commit: a8070b31043c7585c36ba68a74298c4f7af075c3 (2.37-93)
265 -Fix-Commit: 5eea50c4402e39588de98aa1d4469a79774703d4 (2.37-92)
266 -Fix-Commit: f205b3af56740e3b014915b1bd3b162afe3407ef (2.36-167)
267 -Fix-Commit: c34f470a615b136170abd16142da5dd0c024f7d1 (2.36-166)
268 -Fix-Commit: bafadc589fbe21ae330e8c2af74db9da44a17660 (2.35-318)
269 -Fix-Commit: 4370bef52b0f3f3652c6aa13d7a9bb3ac079746d (2.35-317)
270 -Fix-Commit: 1f94122289a9bf7dba573f5d60327aaa2b85cf2e (2.34-462)
271 -Fix-Commit: 966d6ac9e40222b84bb21674cc4f83c8d72a5a26 (2.34-461)
272 -Fix-Commit: e3eef1b8fbdd3a7917af466ca9c4b7477251ca79 (2.33-266)
273 -Fix-Commit: f20a8d696b13c6261b52a6434899121f8b19d5a7 (2.33-265)
274 -Fix-Commit: be602180146de37582a3da3a0caa4b719645de9c (2.32-143)
275 -Fix-Commit: 394eae338199078b7961b051c191539870742d7b (2.32-142)
276 -Fix-Commit: 8d7949183760170c61e55def723c1d8050187874 (2.31-157)
277 -Fix-Commit: 304ce5fe466c4762b21b36c26926a4657b59b53e (2.31-156)
278 diff --git a/advisories/GLIBC-SA-2024-0007 b/advisories/GLIBC-SA-2024-0007
279 deleted file mode 100644
280 index b6928fa27a..0000000000
281 --- a/advisories/GLIBC-SA-2024-0007
282 +++ /dev/null
283 @@ -1,28 +0,0 @@
284 -nscd: netgroup cache may terminate daemon on memory allocation failure
286 -The Name Service Cache Daemon's (nscd) netgroup cache uses xmalloc or
287 -xrealloc and these functions may terminate the process due to a memory
288 -allocation failure resulting in a denial of service to the clients. The
289 -flaw was introduced in glibc 2.15 when the cache was added to nscd.
291 -This vulnerability is only present in the nscd binary.
293 -Subsequent refactoring of the netgroup cache only added more uses of
294 -xmalloc and xrealloc. Uses of xmalloc and xrealloc in other parts of
295 -nscd only occur during startup of the daemon and so are not affected by
296 -client requests that could trigger an out of memory followed by
297 -termination.
299 -CVE-Id: CVE-2024-33601
300 -Public-Date: 2024-04-24
301 -Vulnerable-Commit: 684ae515993269277448150a1ca70db3b94aa5bd (2.15)
302 -Fix-Commit: c04a21e050d64a1193a6daab872bca2528bda44b (2.40)
303 -Fix-Commit: a9a8d3eebb145779a18d90e3966009a1daa63cd8 (2.39-38)
304 -Fix-Commit: 71af8ca864345d39b746d5cee84b94b430fad5db (2.38-75)
305 -Fix-Commit: 6e106dc214d6a033a4e945d1c6cf58061f1c5f1f (2.37-94)
306 -Fix-Commit: b6742463694b1dfdd5120b91ee21cf05d15ec2e2 (2.36-168)
307 -Fix-Commit: 7a5864cac60e06000394128a5a2817b03542f5a3 (2.35-319)
308 -Fix-Commit: 86f1d5f4129c373ac6fb6df5bcf38273838843cb (2.34-463)
309 -Fix-Commit: 4d27d4b9a188786fc6a56745506cec2acfc51f83 (2.33-267)
310 -Fix-Commit: 3ed195a8ec89da281e3c4bf887a13d281b72d8f4 (2.32-144)
311 -Fix-Commit: bbf5a58ccb55679217f94de706164d15372fbbc0 (2.31-158)
312 diff --git a/advisories/GLIBC-SA-2024-0008 b/advisories/GLIBC-SA-2024-0008
313 deleted file mode 100644
314 index d93e2a6f0b..0000000000
315 --- a/advisories/GLIBC-SA-2024-0008
316 +++ /dev/null
317 @@ -1,26 +0,0 @@
318 -nscd: netgroup cache assumes NSS callback uses in-buffer strings
320 -The Name Service Cache Daemon's (nscd) netgroup cache can corrupt memory
321 -when the NSS callback does not store all strings in the provided buffer.
322 -The flaw was introduced in glibc 2.15 when the cache was added to nscd.
324 -This vulnerability is only present in the nscd binary.
326 -There is no guarantee from the NSS callback API that the returned
327 -strings are all within the buffer. However, the netgroup cache code
328 -assumes that the NSS callback uses in-buffer strings and if it doesn't
329 -the buffer resizing logic could lead to potential memory corruption.
331 -CVE-Id: CVE-2024-33602
332 -Public-Date: 2024-04-24
333 -Vulnerable-Commit: 684ae515993269277448150a1ca70db3b94aa5bd (2.15)
334 -Fix-Commit: c04a21e050d64a1193a6daab872bca2528bda44b (2.40)
335 -Fix-Commit: a9a8d3eebb145779a18d90e3966009a1daa63cd8 (2.39-38)
336 -Fix-Commit: 71af8ca864345d39b746d5cee84b94b430fad5db (2.38-75)
337 -Fix-Commit: 6e106dc214d6a033a4e945d1c6cf58061f1c5f1f (2.37-94)
338 -Fix-Commit: b6742463694b1dfdd5120b91ee21cf05d15ec2e2 (2.36-168)
339 -Fix-Commit: 7a5864cac60e06000394128a5a2817b03542f5a3 (2.35-319)
340 -Fix-Commit: 86f1d5f4129c373ac6fb6df5bcf38273838843cb (2.34-463)
341 -Fix-Commit: 4d27d4b9a188786fc6a56745506cec2acfc51f83 (2.33-267)
342 -Fix-Commit: 3ed195a8ec89da281e3c4bf887a13d281b72d8f4 (2.32-144)
343 -Fix-Commit: bbf5a58ccb55679217f94de706164d15372fbbc0 (2.31-158)
344 diff --git a/advisories/README b/advisories/README
345 deleted file mode 100644
346 index b8f8a829ca..0000000000
347 --- a/advisories/README
348 +++ /dev/null
349 @@ -1,77 +0,0 @@
350 -GNU C Library Security Advisory Format
351 -======================================
353 -Security advisories in this directory follow a simple git commit log
354 -format, with a heading and free-format description augmented with tags
355 -to allow parsing key information. References to code changes are
356 -specific to the glibc repository and follow a specific format:
358 - Tag-name: <commit-ref> (release-version)
360 -The <commit-ref> indicates a specific commit in the repository. The
361 -release-version indicates the publicly consumable release in which this
362 -commit is known to exist. The release-version is derived from the
363 -git-describe format, (i.e. stripped out from glibc-2.34.NNN-gxxxx) and
364 -is of the form 2.34-NNN. If the -NNN suffix is absent, it means that
365 -the change is in that release tarball, otherwise the change is on the
366 -release/2.YY/master branch and not in any released tarball.
368 -The following tags are currently being used:
370 -CVE-Id:
371 -This is the CVE-Id assigned under the CVE Program
372 -(https://www.cve.org/).
374 -Public-Date:
375 -The date this issue became publicly known.
377 -Vulnerable-Commit:
378 -The commit that introduced this vulnerability. There could be multiple
379 -entries, one for each release branch in the glibc repository; the
380 -release-version portion of this tag should tell you which branch this is
381 -on.
383 -Fix-Commit:
384 -The commit that fixed this vulnerability. There could be multiple
385 -entries for each release branch in the glibc repository, indicating that
386 -all of those commits contributed to fixing that issue in each of those
387 -branches.
389 -Reported-By:
390 -The entity that reported this issue. There could be multiple entries, one for
391 -each reporter.
393 -Adding an Advisory
394 -------------------
396 -An advisory for a CVE needs to be added on the master branch in two steps:
398 -1. Add the text of the advisory without any Fix-Commit tags along with
399 - the fix for the CVE. Add the Vulnerable-Commit tag, if applicable.
400 - The advisories directory does not exist in release branches, so keep
401 - the advisory text commit distinct from the code changes, to ease
402 - backports. Ask for the GLIBC-SA advisory number from the security
403 - team.
405 -2. Finish all backports on release branches and then back on the msater
406 - branch, add all commit refs to the advisory using the Fix-Commit
407 - tags. Don't bother adding the release-version subscript since the
408 - next step will overwrite it.
410 -3. Run the process-advisories.sh script in the scripts directory on the
411 - advisory:
413 - scripts/process-advisories.sh update GLIBC-SA-YYYY-NNNN
415 - (replace YYYY-NNNN with the actual advisory number).
417 -4. Verify the updated advisory and push the result.
419 -Getting a NEWS snippet from advisories
420 ---------------------------------------
422 -Run:
424 - scripts/process-advisories.sh news
426 -and copy the content into the NEWS file.
428 commit 8bbb8d7b16cae777eed06bc9d2e059fc00be24e9
429 Author: Florian Weimer <fweimer@redhat.com>
430 Date: Wed Jul 24 12:06:47 2024 +0200
432 resolv: Allow short error responses to match any query (bug 31890)
434 Reviewed-by: DJ Delorie <dj@redhat.com>
435 (cherry picked from commit 691a3b2e9bfaba842e46a5ccb7f5e6ea144c3ade)
437 diff --git a/NEWS b/NEWS
438 index 31281ac408..66b755ed34 100644
439 --- a/NEWS
440 +++ b/NEWS
441 @@ -5,6 +5,12 @@ See the end for copying conditions.
442 Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
443 using `glibc' in the "product" field.
445 +Version 2.41
447 +The following bugs are resolved with this release:
449 + [31890] resolv: Allow short error responses to match any DNS query
451 Version 2.40
453 Major new features:
454 diff --git a/resolv/Makefile b/resolv/Makefile
455 index 5f44f5896b..d927e337d9 100644
456 --- a/resolv/Makefile
457 +++ b/resolv/Makefile
458 @@ -106,6 +106,7 @@ tests += \
459 tst-resolv-nondecimal \
460 tst-resolv-res_init-multi \
461 tst-resolv-search \
462 + tst-resolv-short-response \
463 tst-resolv-trailing \
465 # This test calls __res_context_send directly, which is not exported
466 @@ -299,6 +300,8 @@ $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
467 $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
468 $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
469 $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
470 +$(objpfx)tst-resolv-short-response: $(objpfx)libresolv.so \
471 + $(shared-thread-library)
472 $(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
473 $(objpfx)tst-resolv-threads: $(objpfx)libresolv.so $(shared-thread-library)
474 $(objpfx)tst-resolv-txnid-collision: $(objpfx)libresolv.a \
475 diff --git a/resolv/res_send.c b/resolv/res_send.c
476 index ea7cf192b2..572e72c32f 100644
477 --- a/resolv/res_send.c
478 +++ b/resolv/res_send.c
479 @@ -1199,19 +1199,30 @@ send_dg(res_state statp,
482 /* Check for the correct header layout and a matching
483 - question. */
484 + question. Some recursive resolvers send REFUSED
485 + without copying back the question section
486 + (producing a response that is only HFIXEDSZ bytes
487 + long). Skip query matching in this case. */
488 + bool thisansp_error = (anhp->rcode == SERVFAIL ||
489 + anhp->rcode == NOTIMP ||
490 + anhp->rcode == REFUSED);
491 + bool skip_query_match = (*thisresplenp == HFIXEDSZ
492 + && ntohs (anhp->qdcount) == 0
493 + && thisansp_error);
494 int matching_query = 0; /* Default to no matching query. */
495 if (!recvresp1
496 && anhp->id == hp->id
497 - && __libc_res_queriesmatch (buf, buf + buflen,
498 - *thisansp,
499 - *thisansp + *thisanssizp))
500 + && (skip_query_match
501 + || __libc_res_queriesmatch (buf, buf + buflen,
502 + *thisansp,
503 + *thisansp + *thisanssizp)))
504 matching_query = 1;
505 if (!recvresp2
506 && anhp->id == hp2->id
507 - && __libc_res_queriesmatch (buf2, buf2 + buflen2,
508 - *thisansp,
509 - *thisansp + *thisanssizp))
510 + && (skip_query_match
511 + || __libc_res_queriesmatch (buf2, buf2 + buflen2,
512 + *thisansp,
513 + *thisansp + *thisanssizp)))
514 matching_query = 2;
515 if (matching_query == 0)
516 /* Spurious UDP packet. Drop it and continue
517 @@ -1221,9 +1232,7 @@ send_dg(res_state statp,
518 goto wait;
521 - if (anhp->rcode == SERVFAIL ||
522 - anhp->rcode == NOTIMP ||
523 - anhp->rcode == REFUSED) {
524 + if (thisansp_error) {
525 next_ns:
526 if (recvresp1 || (buf2 != NULL && recvresp2)) {
527 *resplen2 = 0;
528 diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c
529 new file mode 100644
530 index 0000000000..cf1e39876f
531 --- /dev/null
532 +++ b/resolv/tst-resolv-short-response.c
533 @@ -0,0 +1,112 @@
534 +/* Test for spurious timeouts with short 12-byte responses (bug 31890).
535 + Copyright (C) 2024 Free Software Foundation, Inc.
536 + This file is part of the GNU C Library.
538 + The GNU C Library is free software; you can redistribute it and/or
539 + modify it under the terms of the GNU Lesser General Public
540 + License as published by the Free Software Foundation; either
541 + version 2.1 of the License, or (at your option) any later version.
543 + The GNU C Library is distributed in the hope that it will be useful,
544 + but WITHOUT ANY WARRANTY; without even the implied warranty of
545 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
546 + Lesser General Public License for more details.
548 + You should have received a copy of the GNU Lesser General Public
549 + License along with the GNU C Library; if not, see
550 + <https://www.gnu.org/licenses/>. */
552 +#include <resolv.h>
553 +#include <support/check.h>
554 +#include <support/resolv_test.h>
555 +#include <support/check_nss.h>
557 +/* The rcode in the initial response. */
558 +static volatile int rcode;
560 +static void
561 +response (const struct resolv_response_context *ctx,
562 + struct resolv_response_builder *b,
563 + const char *qname, uint16_t qclass, uint16_t qtype)
565 + switch (ctx->server_index)
567 + case 0:
568 + /* First server times out. */
569 + struct resolv_response_flags flags = {.rcode = rcode};
570 + resolv_response_init (b, flags);
571 + break;
572 + case 1:
573 + /* Second server sends reply. */
574 + resolv_response_init (b, (struct resolv_response_flags) {});
575 + resolv_response_add_question (b, qname, qclass, qtype);
576 + resolv_response_section (b, ns_s_an);
577 + resolv_response_open_record (b, qname, qclass, qtype, 0);
578 + switch (qtype)
580 + case T_A:
582 + char ipv4[4] = {192, 0, 2, 17};
583 + resolv_response_add_data (b, &ipv4, sizeof (ipv4));
585 + break;
586 + case T_AAAA:
588 + char ipv6[16]
589 + = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
590 + resolv_response_add_data (b, &ipv6, sizeof (ipv6));
592 + break;
593 + default:
594 + FAIL_EXIT1 ("unexpected TYPE%d query", qtype);
596 + resolv_response_close_record (b);
597 + break;
598 + default:
599 + FAIL_EXIT1 ("unexpected query to server %d", ctx->server_index);
603 +static void
604 +check_one (void)
607 + /* The buggy 1-second query timeout results in 30 seconds of delay,
608 + which triggers a test timeout failure. */
609 + for (int i = 0; i < 10; ++i)
611 + check_hostent ("www.example", gethostbyname ("www.example"),
612 + "name: www.example\n"
613 + "address: 192.0.2.17\n");
614 + check_hostent ("www.example", gethostbyname2 ("www.example", AF_INET6),
615 + "name: www.example\n"
616 + "address: 2001:db8::1\n");
620 +static int
621 +do_test (void)
623 + struct resolv_test *aux = resolv_test_start
624 + ((struct resolv_redirect_config)
626 + .response_callback = response,
627 + });
629 + _res.options |= RES_SNGLKUP;
631 + rcode = 2; /* SERVFAIL. */
632 + check_one ();
634 + rcode = 4; /* NOTIMP. */
635 + check_one ();
637 + rcode = 5; /* REFUSED. */
638 + check_one ();
640 + resolv_test_end (aux);
642 + return 0;
645 +#include <support/test-driver.c>
647 commit ef141426630da0946f0af8732eddce9b9a52b2d3
648 Author: Florian Weimer <fweimer@redhat.com>
649 Date: Wed Jul 24 12:06:47 2024 +0200
651 resolv: Do not wait for non-existing second DNS response after error (bug 30081)
653 In single-request mode, there is no second response after an error
654 because the second query has not been sent yet. Waiting for it
655 introduces an unnecessary timeout.
657 Reviewed-by: DJ Delorie <dj@redhat.com>
658 (cherry picked from commit af625987d619388a100b153520d3ee308bda9889)
660 diff --git a/NEWS b/NEWS
661 index 66b755ed34..4d7100b21c 100644
662 --- a/NEWS
663 +++ b/NEWS
664 @@ -9,6 +9,7 @@ Version 2.41
666 The following bugs are resolved with this release:
668 + [30081] resolv: Do not wait for non-existing second DNS response after error
669 [31890] resolv: Allow short error responses to match any DNS query
671 Version 2.40
672 diff --git a/resolv/Makefile b/resolv/Makefile
673 index d927e337d9..abff7fc007 100644
674 --- a/resolv/Makefile
675 +++ b/resolv/Makefile
676 @@ -106,6 +106,7 @@ tests += \
677 tst-resolv-nondecimal \
678 tst-resolv-res_init-multi \
679 tst-resolv-search \
680 + tst-resolv-semi-failure \
681 tst-resolv-short-response \
682 tst-resolv-trailing \
684 @@ -300,6 +301,8 @@ $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
685 $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
686 $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
687 $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
688 +$(objpfx)tst-resolv-semi-failure: $(objpfx)libresolv.so \
689 + $(shared-thread-library)
690 $(objpfx)tst-resolv-short-response: $(objpfx)libresolv.so \
691 $(shared-thread-library)
692 $(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
693 diff --git a/resolv/res_send.c b/resolv/res_send.c
694 index 572e72c32f..9c77613f37 100644
695 --- a/resolv/res_send.c
696 +++ b/resolv/res_send.c
697 @@ -1238,7 +1238,7 @@ send_dg(res_state statp,
698 *resplen2 = 0;
699 return resplen;
701 - if (buf2 != NULL)
702 + if (buf2 != NULL && !single_request)
704 /* No data from the first reply. */
705 resplen = 0;
706 diff --git a/resolv/tst-resolv-semi-failure.c b/resolv/tst-resolv-semi-failure.c
707 new file mode 100644
708 index 0000000000..aa9798b5a7
709 --- /dev/null
710 +++ b/resolv/tst-resolv-semi-failure.c
711 @@ -0,0 +1,133 @@
712 +/* Test parallel failure/success responses (bug 30081).
713 + Copyright (C) 2024 Free Software Foundation, Inc.
714 + This file is part of the GNU C Library.
716 + The GNU C Library is free software; you can redistribute it and/or
717 + modify it under the terms of the GNU Lesser General Public
718 + License as published by the Free Software Foundation; either
719 + version 2.1 of the License, or (at your option) any later version.
721 + The GNU C Library is distributed in the hope that it will be useful,
722 + but WITHOUT ANY WARRANTY; without even the implied warranty of
723 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
724 + Lesser General Public License for more details.
726 + You should have received a copy of the GNU Lesser General Public
727 + License along with the GNU C Library; if not, see
728 + <https://www.gnu.org/licenses/>. */
730 +#include <resolv.h>
731 +#include <support/check.h>
732 +#include <support/resolv_test.h>
733 +#include <support/check_nss.h>
735 +/* The rcode in the initial response. */
736 +static volatile int rcode;
738 +/* Whether to fail the initial A query (!fail_aaaa) or the initial
739 + AAAA query (fail_aaaa). */
740 +static volatile bool fail_aaaa;
742 +static void
743 +response (const struct resolv_response_context *ctx,
744 + struct resolv_response_builder *b,
745 + const char *qname, uint16_t qclass, uint16_t qtype)
747 + /* Handle the failing query. */
748 + if ((fail_aaaa && qtype == T_AAAA) && ctx->server_index == 0)
750 + struct resolv_response_flags flags = {.rcode = rcode};
751 + resolv_response_init (b, flags);
752 + return;
755 + /* Otherwise produce a response. */
756 + resolv_response_init (b, (struct resolv_response_flags) {});
757 + resolv_response_add_question (b, qname, qclass, qtype);
758 + resolv_response_section (b, ns_s_an);
759 + resolv_response_open_record (b, qname, qclass, qtype, 0);
760 + switch (qtype)
762 + case T_A:
764 + char ipv4[4] = {192, 0, 2, 17};
765 + resolv_response_add_data (b, &ipv4, sizeof (ipv4));
767 + break;
768 + case T_AAAA:
770 + char ipv6[16]
771 + = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
772 + resolv_response_add_data (b, &ipv6, sizeof (ipv6));
774 + break;
775 + default:
776 + FAIL_EXIT1 ("unexpected TYPE%d query", qtype);
778 + resolv_response_close_record (b);
781 +static void
782 +check_one (void)
785 + /* The buggy 1-second query timeout results in 30 seconds of delay,
786 + which triggers are test timeout failure. */
787 + for (int i = 0; i < 30; ++i)
789 + static const struct addrinfo hints =
791 + .ai_family = AF_UNSPEC,
792 + .ai_socktype = SOCK_STREAM,
793 + };
794 + struct addrinfo *ai;
795 + int ret = getaddrinfo ("www.example", "80", &hints, &ai);
796 + const char *expected;
797 + if (ret == 0 && ai->ai_next != NULL)
798 + expected = ("address: STREAM/TCP 192.0.2.17 80\n"
799 + "address: STREAM/TCP 2001:db8::1 80\n");
800 + else
801 + /* Only one response because the AAAA lookup failure is
802 + treated as an ignoreable error. */
803 + expected = "address: STREAM/TCP 192.0.2.17 80\n";
804 + check_addrinfo ("www.example", ai, ret, expected);
805 + if (ret == 0)
806 + freeaddrinfo (ai);
810 +static int
811 +do_test (void)
813 + for (int do_single_lookup = 0; do_single_lookup < 2; ++do_single_lookup)
815 + struct resolv_test *aux = resolv_test_start
816 + ((struct resolv_redirect_config)
818 + .response_callback = response,
819 + });
821 + if (do_single_lookup)
822 + _res.options |= RES_SNGLKUP;
824 + for (int do_fail_aaaa = 0; do_fail_aaaa < 2; ++do_fail_aaaa)
826 + fail_aaaa = do_fail_aaaa;
828 + rcode = 2; /* SERVFAIL. */
829 + check_one ();
831 + rcode = 4; /* NOTIMP. */
832 + check_one ();
834 + rcode = 5; /* REFUSED. */
835 + check_one ();
838 + resolv_test_end (aux);
841 + return 0;
844 +#include <support/test-driver.c>
845 diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c
846 index cf1e39876f..be354ae1c7 100644
847 --- a/resolv/tst-resolv-short-response.c
848 +++ b/resolv/tst-resolv-short-response.c
849 @@ -81,6 +81,18 @@ check_one (void)
850 check_hostent ("www.example", gethostbyname2 ("www.example", AF_INET6),
851 "name: www.example\n"
852 "address: 2001:db8::1\n");
853 + static const struct addrinfo hints =
855 + .ai_family = AF_UNSPEC,
856 + .ai_socktype = SOCK_STREAM,
857 + };
858 + struct addrinfo *ai;
859 + int ret = getaddrinfo ("www.example", "80", &hints, &ai);
860 + check_addrinfo ("www.example", ai, ret,
861 + "address: STREAM/TCP 192.0.2.17 80\n"
862 + "address: STREAM/TCP 2001:db8::1 80\n");
863 + if (ret == 0)
864 + freeaddrinfo (ai);
869 commit b6aeba2de157ba0cdc8fb0aed67b632b3490f383
870 Author: Florian Weimer <fweimer@redhat.com>
871 Date: Wed Jul 24 12:50:17 2024 +0200
873 manual: Do not mention STATIC_TLS in dynamic linker hardening recommendations
875 The current toolchain does not consistently generate it, and
876 glibc does not use it.
878 Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
879 (cherry picked from commit 90842d3980064ef410b998b22170ad409b76b9fd)
881 diff --git a/manual/dynlink.texi b/manual/dynlink.texi
882 index 03565d4fb0..1500a53de6 100644
883 --- a/manual/dynlink.texi
884 +++ b/manual/dynlink.texi
885 @@ -993,21 +993,21 @@ The dynamic segment should also mention @code{BIND_NOW} on the
886 enough).
888 @item
889 -For shared objects (not main programs), if the program header has a
890 -@code{PT_TLS} segment, the dynamic segment (as shown by @samp{readelf
891 --dW}) should contain the @code{STATIC_TLS} flag on the @code{FLAGS}
892 -line.
894 -If @code{STATIC_TLS} is missing in shared objects, ensure that the
895 -appropriate relocations for GNU2 TLS descriptors are used (for example,
896 +Ensure that only static TLS relocations (thread-pointer relative offset
897 +locations) are used, for example @code{R_AARCH64_TLS_TPREL} and
898 +@code{X86_64_TPOFF64}. As the second-best option, and only if
899 +compatibility with non-hardened applications using @code{dlopen} is
900 +needed, GNU2 TLS descriptor relocations can be used (for example,
901 @code{R_AARCH64_TLSDESC} or @code{R_X86_64_TLSDESC}).
903 @item
904 -There should not be a reference to the symbols @code{__tls_get_addr},
905 -@code{__tls_get_offset}, @code{__tls_get_addr_opt} in the dynamic symbol
906 -table (in the @samp{readelf -sDW} output). Thread-local storage must be
907 -accessed using the initial-exec (static) model, or using GNU2 TLS
908 -descriptors.
909 +There should not be references to the traditional TLS function symbols
910 +@code{__tls_get_addr}, @code{__tls_get_offset},
911 +@code{__tls_get_addr_opt} in the dynamic symbol table (in the
912 +@samp{readelf -sDW} output). Supporting global dynamic TLS relocations
913 +(such as @code{R_AARCH64_TLS_DTPMOD}, @code{R_AARCH64_TLS_DTPREL},
914 +@code{R_X86_64_DTPMOD64}, @code{R_X86_64_DTPOFF64}) should not be used,
915 +either.
917 @item
918 Likewise, the functions @code{dlopen}, @code{dlmopen}, @code{dlclose}
920 commit 145b5886379c8de4f0a1bca3556a4c3d7b6c24b2
921 Author: Florian Weimer <fweimer@redhat.com>
922 Date: Wed Jul 24 13:42:16 2024 +0200
924 Fix version number in NEWS file
926 diff --git a/NEWS b/NEWS
927 index 4d7100b21c..6b62f55658 100644
928 --- a/NEWS
929 +++ b/NEWS
930 @@ -5,7 +5,7 @@ See the end for copying conditions.
931 Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
932 using `glibc' in the "product" field.
934 -Version 2.41
935 +Version 2.40.1
937 The following bugs are resolved with this release:
940 commit 2aebac5e158277d852b87b0cbd4af2b2d10ac387
941 Author: Miguel Martín <mmartinv@redhat.com>
942 Date: Tue Jul 16 17:14:56 2024 +0200
944 malloc: avoid global locks in tst-aligned_alloc-lib.c
946 Make sure the DSO used by aligned_alloc/calloc/malloc tests does not get
947 a global lock on multithreaded tests.
948 Reviewed-by: Arjun Shankar <arjun@redhat.com>
950 (cherry picked from commit 9a27b566b2048f599048f2f4afe1cce06c4ef43d)
952 diff --git a/malloc/tst-aligned_alloc-lib.c b/malloc/tst-aligned_alloc-lib.c
953 index 0205df5acf..9ef1f839c1 100644
954 --- a/malloc/tst-aligned_alloc-lib.c
955 +++ b/malloc/tst-aligned_alloc-lib.c
956 @@ -17,37 +17,38 @@
957 License along with the GNU C Library; see the file COPYING.LIB. If
958 not, see <https://www.gnu.org/licenses/>. */
960 -#include <array_length.h>
961 #include <libc-symbols.h>
962 #include <stdlib.h>
963 +#include <time.h>
965 extern void *__libc_malloc (size_t size);
966 extern void *__libc_calloc (size_t n, size_t size);
968 +__thread unsigned int seed = 0;
970 int aligned_alloc_count = 0;
971 int libc_malloc_count = 0;
972 int libc_calloc_count = 0;
974 -/* Get a random alignment value. Biased towards the smaller values. Must be
975 - a power of 2. */
976 -static size_t get_random_alignment (void)
978 - size_t aligns[] = {
979 - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384
980 - };
982 - return aligns[random () % array_length (aligns)];
985 -static void *get_random_alloc (size_t size)
986 +static void *
987 +get_random_alloc (size_t size)
989 void *retval;
990 size_t align;
991 + struct timespec tp;
993 + if (seed == 0)
995 + clock_gettime (CLOCK_REALTIME, &tp);
996 + seed = tp.tv_nsec;
999 - switch (random() % 3)
1001 + switch (rand_r (&seed) % 3)
1003 case 1:
1004 - align = get_random_alignment ();
1005 + /* Get a random alignment value. Biased towards the smaller
1006 + * values up to 16384. Must be a power of 2. */
1007 + align = 1 << rand_r (&seed) % 15;
1008 retval = aligned_alloc (align, size);
1009 aligned_alloc_count++;
1010 break;
1011 @@ -59,13 +60,13 @@ static void *get_random_alloc (size_t size)
1012 retval = __libc_malloc (size);
1013 libc_malloc_count++;
1014 break;
1018 return retval;
1022 -void * __random_malloc (size_t size)
1023 +void *
1024 +__random_malloc (size_t size)
1026 return get_random_alloc (size);
1029 commit 5d2a931a8167a288374c3a38dc10fe0492ab5ffe
1030 Author: Miguel Martín <mmartinv@redhat.com>
1031 Date: Tue Jul 16 17:14:57 2024 +0200
1033 malloc: add multi-threaded tests for aligned_alloc/calloc/malloc
1035 Improve aligned_alloc/calloc/malloc test coverage by adding
1036 multi-threaded tests with random memory allocations and with/without
1037 cross-thread memory deallocations.
1039 Perform a number of memory allocation calls with random sizes limited
1040 to 0xffff.
1042 Use the existing DSO ('malloc/tst-aligned_alloc-lib.c') to randomize
1043 allocator selection.
1045 The multi-threaded allocation/deallocation is staged as described below:
1047 - Stage 1: Half of the threads will be allocating memory and the
1048 other half will be waiting for them to finish the allocation.
1049 - Stage 2: Half of the threads will be allocating memory and the
1050 other half will be deallocating memory.
1051 - Stage 3: Half of the threads will be deallocating memory and the
1052 second half waiting on them to finish.
1054 Add 'malloc/tst-aligned-alloc-random-thread.c' where each thread will
1055 deallocate only the memory that was previously allocated by itself.
1057 Add 'malloc/tst-aligned-alloc-random-thread-cross.c' where each thread
1058 will deallocate memory that was previously allocated by another thread.
1060 The intention is to be able to utilize existing malloc testing to ensure
1061 that similar allocation APIs are also exposed to the same rigors.
1062 Reviewed-by: Arjun Shankar <arjun@redhat.com>
1064 (cherry picked from commit b0fbcb7d0051a68baf26b2aed51a8a31c34d68e5)
1066 diff --git a/malloc/Makefile b/malloc/Makefile
1067 index 02aff1bd1d..98d507a6eb 100644
1068 --- a/malloc/Makefile
1069 +++ b/malloc/Makefile
1070 @@ -28,6 +28,8 @@ tests := \
1071 mallocbug \
1072 tst-aligned-alloc \
1073 tst-aligned-alloc-random \
1074 + tst-aligned-alloc-random-thread \
1075 + tst-aligned-alloc-random-thread-cross \
1076 tst-alloc_buffer \
1077 tst-calloc \
1078 tst-free-errno \
1079 @@ -151,6 +153,8 @@ ifeq ($(have-GLIBC_2.23)$(build-shared),yesyes)
1080 # the tests expect specific internal behavior that is changed due to linking to
1081 # libmcheck.a.
1082 tests-exclude-mcheck = \
1083 + tst-aligned-alloc-random-thread \
1084 + tst-aligned-alloc-random-thread-cross \
1085 tst-compathooks-off \
1086 tst-compathooks-on \
1087 tst-malloc-backtrace \
1088 @@ -415,7 +419,11 @@ $(objpfx)tst-mallocstate: $(objpfx)libc_malloc_debug.so
1089 $(objpfx)tst-mallocstate-malloc-check: $(objpfx)libc_malloc_debug.so
1091 $(objpfx)tst-aligned-alloc-random.out: $(objpfx)tst-aligned_alloc-lib.so
1092 +$(objpfx)tst-aligned-alloc-random-thread.out: $(objpfx)tst-aligned_alloc-lib.so
1093 +$(objpfx)tst-aligned-alloc-random-thread-cross.out: $(objpfx)tst-aligned_alloc-lib.so
1094 $(objpfx)tst-malloc-random.out: $(objpfx)tst-aligned_alloc-lib.so
1096 tst-aligned-alloc-random-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so
1097 +tst-aligned-alloc-random-thread-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so
1098 +tst-aligned-alloc-random-thread-cross-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so
1099 tst-malloc-random-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so
1100 diff --git a/malloc/tst-aligned-alloc-random-thread-cross.c b/malloc/tst-aligned-alloc-random-thread-cross.c
1101 new file mode 100644
1102 index 0000000000..360ecc56ee
1103 --- /dev/null
1104 +++ b/malloc/tst-aligned-alloc-random-thread-cross.c
1105 @@ -0,0 +1,19 @@
1106 +/* multi-threaded memory allocation and cross-thread deallocation test.
1107 + Copyright (C) 2024 Free Software Foundation, Inc.
1108 + This file is part of the GNU C Library.
1110 + The GNU C Library is free software; you can redistribute it and/or
1111 + modify it under the terms of the GNU Lesser General Public License as
1112 + published by the Free Software Foundation; either version 2.1 of the
1113 + License, or (at your option) any later version.
1115 + The GNU C Library is distributed in the hope that it will be useful,
1116 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1117 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1118 + Lesser General Public License for more details.
1120 + You should have received a copy of the GNU Lesser General Public
1121 + License along with the GNU C Library; see the file COPYING.LIB. If
1122 + not, see <https://www.gnu.org/licenses/>. */
1123 +#define CROSS_THREAD_DEALLOC
1124 +#include "tst-aligned-alloc-random-thread.c"
1125 diff --git a/malloc/tst-aligned-alloc-random-thread.c b/malloc/tst-aligned-alloc-random-thread.c
1126 new file mode 100644
1127 index 0000000000..e95f79250a
1128 --- /dev/null
1129 +++ b/malloc/tst-aligned-alloc-random-thread.c
1130 @@ -0,0 +1,145 @@
1131 +/* multi-threaded memory allocation/deallocation test.
1132 + Copyright (C) 2024 Free Software Foundation, Inc.
1133 + This file is part of the GNU C Library.
1135 + The GNU C Library is free software; you can redistribute it and/or
1136 + modify it under the terms of the GNU Lesser General Public License as
1137 + published by the Free Software Foundation; either version 2.1 of the
1138 + License, or (at your option) any later version.
1140 + The GNU C Library is distributed in the hope that it will be useful,
1141 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1142 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1143 + Lesser General Public License for more details.
1145 + You should have received a copy of the GNU Lesser General Public
1146 + License along with the GNU C Library; see the file COPYING.LIB. If
1147 + not, see <https://www.gnu.org/licenses/>. */
1149 +#include <stdio.h>
1150 +#include <stdlib.h>
1151 +#include <string.h>
1152 +#include <support/check.h>
1153 +#include <support/support.h>
1154 +#include <support/xthread.h>
1155 +#include <support/test-driver.h>
1156 +#include <sys/sysinfo.h>
1157 +#include <unistd.h>
1159 +#ifndef ITERATIONS
1160 +# define ITERATIONS 16
1161 +#endif
1163 +#ifndef NUM_THREADS
1164 +# define NUM_THREADS 8
1165 +#endif
1167 +#ifndef NUM_ALLOCATIONS
1168 +# define NUM_ALLOCATIONS 2048
1169 +#endif
1171 +static pthread_barrier_t barrier;
1173 +__thread unsigned int seed;
1175 +typedef struct
1177 + int id;
1178 + pthread_t thread;
1179 +} thread;
1181 +thread threads[NUM_THREADS];
1183 +void *allocations[NUM_THREADS][NUM_ALLOCATIONS];
1185 +void
1186 +run_thread_dealloc (int id)
1188 + for (int i = 0; i < NUM_ALLOCATIONS; i++)
1190 + free (allocations[id][i]);
1191 + allocations[id][i] = NULL;
1195 +void
1196 +run_thread_alloc (int id)
1198 + size_t msb, size;
1199 + for (int i = 0; i < NUM_ALLOCATIONS; i++)
1201 + msb = 1 << rand_r (&seed) % 16;
1202 + size = msb + rand_r (&seed) % msb;
1203 + allocations[id][i] = malloc (size);
1204 + TEST_VERIFY_EXIT (allocations[id][i] != NULL);
1208 +void *
1209 +run_allocations (void *arg)
1211 + int id = *((int *) arg);
1212 + seed = time (NULL) + id;
1214 + /* Stage 1: First half o the threads allocating memory and the second
1215 + * half waiting for them to finish
1216 + */
1217 + if (id < NUM_THREADS / 2)
1218 + run_thread_alloc (id);
1220 + xpthread_barrier_wait (&barrier);
1222 + /* Stage 2: Half of the threads allocationg memory and the other
1223 + * half deallocating:
1224 + * - In the non cross-thread dealloc scenario the first half will be
1225 + * deallocating the memory allocated by themselves in stage 1 and the
1226 + * second half will be allocating memory.
1227 + * - In the cross-thread dealloc scenario the first half will continue
1228 + * to allocate memory and the second half will deallocate the memory
1229 + * allocated by the first half in stage 1.
1230 + */
1231 + if (id < NUM_THREADS / 2)
1232 +#ifndef CROSS_THREAD_DEALLOC
1233 + run_thread_dealloc (id);
1234 +#else
1235 + run_thread_alloc (id + NUM_THREADS / 2);
1236 +#endif
1237 + else
1238 +#ifndef CROSS_THREAD_DEALLOC
1239 + run_thread_alloc (id);
1240 +#else
1241 + run_thread_dealloc (id - NUM_THREADS / 2);
1242 +#endif
1244 + xpthread_barrier_wait (&barrier);
1246 + // Stage 3: Second half of the threads deallocating and the first half
1247 + // waiting for them to finish.
1248 + if (id >= NUM_THREADS / 2)
1249 + run_thread_dealloc (id);
1251 + return NULL;
1254 +static int
1255 +do_test (void)
1257 + xpthread_barrier_init (&barrier, NULL, NUM_THREADS);
1259 + for (int i = 0; i < ITERATIONS; i++)
1261 + for (int t = 0; t < NUM_THREADS; t++)
1263 + threads[t].id = t;
1264 + threads[t].thread
1265 + = xpthread_create (NULL, run_allocations, &threads[t].id);
1268 + for (int t = 0; t < NUM_THREADS; t++)
1269 + xpthread_join (threads[t].thread);
1272 + return 0;
1275 +#include <support/test-driver.c>
1277 commit 65fbcfe58991194301a7e4fb9c53ab936573e711
1278 Author: Arjun Shankar <arjun@redhat.com>
1279 Date: Mon Jul 29 14:30:59 2024 +0200
1281 manual/stdio: Clarify putc and putwc
1283 The manual entry for `putc' described what "most systems" do instead of
1284 describing the glibc implementation and its guarantees. This commit
1285 fixes that by warning that putc may be implemented as a macro that
1286 double-evaluates `stream', and removing the performance claim.
1288 Even though the current `putc' implementation does not double-evaluate
1289 `stream', offering this obscure guarantee as an extension to what
1290 POSIX allows does not seem very useful.
1292 The entry for `putwc' is also edited to bring it in line with `putc'.
1293 Reviewed-by: Florian Weimer <fweimer@redhat.com>
1295 (cherry picked from commit 10de4a47ef3f481592e3c62eb07bcda23e9fde4d)
1297 diff --git a/manual/stdio.texi b/manual/stdio.texi
1298 index f5e289d58a..f9529a098d 100644
1299 --- a/manual/stdio.texi
1300 +++ b/manual/stdio.texi
1301 @@ -903,21 +903,21 @@ This function is a GNU extension.
1302 @deftypefun int putc (int @var{c}, FILE *@var{stream})
1303 @standards{ISO, stdio.h}
1304 @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
1305 -This is just like @code{fputc}, except that most systems implement it as
1306 +This is just like @code{fputc}, except that it may be implemented as
1307 a macro, making it faster. One consequence is that it may evaluate the
1308 @var{stream} argument more than once, which is an exception to the
1309 -general rule for macros. @code{putc} is usually the best function to
1310 -use for writing a single character.
1311 +general rule for macros. Therefore, @var{stream} should never be an
1312 +expression with side-effects.
1313 @end deftypefun
1315 @deftypefun wint_t putwc (wchar_t @var{wc}, FILE *@var{stream})
1316 @standards{ISO, wchar.h}
1317 @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
1318 -This is just like @code{fputwc}, except that it can be implement as
1319 +This is just like @code{fputwc}, except that it may be implemented as
1320 a macro, making it faster. One consequence is that it may evaluate the
1321 @var{stream} argument more than once, which is an exception to the
1322 -general rule for macros. @code{putwc} is usually the best function to
1323 -use for writing a single wide character.
1324 +general rule for macros. Therefore, @var{stream} should never be an
1325 +expression with side-effects.
1326 @end deftypefun
1328 @deftypefun int putc_unlocked (int @var{c}, FILE *@var{stream})
1330 commit 132a72f93cb4ad9f16b8469dc061de5f75f6a44e
1331 Author: Lukas Bulwahn <lukas.bulwahn@redhat.com>
1332 Date: Mon Jul 29 11:08:17 2024 +0200
1334 manual: make setrlimit() description less ambiguous
1336 The existing description for setrlimit() has some ambiguity. It could be
1337 understood to have the semantics of getrlimit(), i.e., the limits from the
1338 process are stored in the provided rlp pointer.
1340 Make the description more explicit that rlp are the input values, and that
1341 the limits of the process is changed with this function.
1343 Reviewed-by: Florian Weimer <fweimer@redhat.com>
1344 (cherry picked from commit aedbf08891069fc029ed021e4dba933eb877b394)
1346 diff --git a/manual/resource.texi b/manual/resource.texi
1347 index c9b21dedeb..25966bcb64 100644
1348 --- a/manual/resource.texi
1349 +++ b/manual/resource.texi
1350 @@ -192,8 +192,8 @@ If the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
1351 @standards{BSD, sys/resource.h}
1352 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
1353 @c Direct syscall on most systems; lock-taking critical section on HURD.
1354 -Store the current and maximum limits for the resource @var{resource}
1355 -in @code{*@var{rlp}}.
1356 +Change the current and maximum limits of the process for the resource
1357 +@var{resource} to the values provided in @code{*@var{rlp}}.
1359 The return value is @code{0} on success and @code{-1} on failure. The
1360 following @code{errno} error condition is possible:
1362 commit 509166c9a53ad81217a28cc67ba2a688f02fc477
1363 Author: Florian Weimer <fweimer@redhat.com>
1364 Date: Wed Jun 26 11:27:54 2024 +0200
1366 Enhance test coverage for strnlen, wcsnlen
1368 This commit adds string/test-strnlen-nonarray and
1369 wcsmbs/test-wcsnlen-nonarray.
1371 Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
1372 (cherry picked from commit 783d4c0b81889c39a9ddf13b60d0fde4040fb1c0)
1374 diff --git a/string/Makefile b/string/Makefile
1375 index 8f31fa49e6..2e20fc00fd 100644
1376 --- a/string/Makefile
1377 +++ b/string/Makefile
1378 @@ -184,6 +184,7 @@ tests := \
1379 test-strncpy \
1380 test-strndup \
1381 test-strnlen \
1382 + test-strnlen-nonarray \
1383 test-strpbrk \
1384 test-strrchr \
1385 test-strspn \
1386 diff --git a/string/test-Xnlen-nonarray.c b/string/test-Xnlen-nonarray.c
1387 new file mode 100644
1388 index 0000000000..499bef2041
1389 --- /dev/null
1390 +++ b/string/test-Xnlen-nonarray.c
1391 @@ -0,0 +1,133 @@
1392 +/* Test non-array inputs to string length functions.
1393 + Copyright (C) 2024 Free Software Foundation, Inc.
1394 + This file is part of the GNU C Library.
1396 + The GNU C Library is free software; you can redistribute it and/or
1397 + modify it under the terms of the GNU Lesser General Public
1398 + License as published by the Free Software Foundation; either
1399 + version 2.1 of the License, or (at your option) any later version.
1401 + The GNU C Library is distributed in the hope that it will be useful,
1402 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1403 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1404 + Lesser General Public License for more details.
1406 + You should have received a copy of the GNU Lesser General Public
1407 + License along with the GNU C Library; if not, see
1408 + <https://www.gnu.org/licenses/>. */
1410 +/* This skeleton file is included from string/test-strnlen-nonarray.c
1411 + and wcsmbs/test-wcsnlen-nonarray.c to test that reading of the array
1412 + stops at the first null character.
1414 + TEST_IDENTIFIER must be the test function identifier. TEST_NAME is
1415 + the same as a string.
1417 + CHAR must be defined as the character type. */
1419 +#include <array_length.h>
1420 +#include <string.h>
1421 +#include <support/check.h>
1422 +#include <support/next_to_fault.h>
1423 +#include <support/test-driver.h>
1424 +#include <sys/param.h>
1425 +#include <unistd.h>
1427 +typedef __typeof (TEST_IDENTIFIER) *proto_t;
1429 +#define TEST_MAIN
1430 +#include "test-string.h"
1432 +IMPL (TEST_IDENTIFIER, 1)
1434 +static int
1435 +test_main (void)
1437 + enum { buffer_length = 256 };
1438 + TEST_VERIFY_EXIT (sysconf (_SC_PAGESIZE) >= buffer_length);
1440 + test_init ();
1442 + /* Buffer layout: There are a_count 'A' character followed by
1443 + zero_count null character, for a total of buffer_length
1444 + character:
1446 + AAAAA...AAAAA 00000 ... 00000 (unmapped page follows)
1447 + \ / \ /
1448 + (a_count) (zero_count)
1449 + \___ (buffer_length) ___/
1452 + start_offset
1454 + The buffer length does not change, but a_count (and thus _zero)
1455 + and start_offset vary.
1457 + If start_offset == buffer_length, only 0 is a valid length
1458 + argument. The result is 0.
1460 + Otherwwise, if zero_count > 0 (if there a null characters in the
1461 + buffer), then any length argument is valid. If start_offset <
1462 + a_count (i.e., there is a non-null character at start_offset), the
1463 + result is the minimum of a_count - start_offset and the length
1464 + argument. Otherwise the result is 0.
1466 + Otherwise, there are no null characters before the unmapped page.
1467 + The length argument must not be greater than buffer_length -
1468 + start_offset, and the result is the length argument. */
1470 + struct support_next_to_fault ntf
1471 + = support_next_to_fault_allocate (buffer_length * sizeof (CHAR));
1472 + CHAR *buffer = (CHAR *) ntf.buffer;
1474 + FOR_EACH_IMPL (impl, 0)
1476 + printf ("info: testing %s\n", impl->name);
1477 + for (size_t i = 0; i < buffer_length; ++i)
1478 + buffer[i] = 'A';
1480 + for (int zero_count = 0; zero_count <= buffer_length; ++zero_count)
1482 + if (zero_count > 0)
1483 + buffer[buffer_length - zero_count] = 0;
1484 + int a_count = buffer_length - zero_count;
1485 + for (int start_offset = 0; start_offset <= buffer_length;
1486 + ++start_offset)
1488 + CHAR *start_pointer = buffer + start_offset;
1489 + if (start_offset == buffer_length)
1490 + TEST_COMPARE (CALL (impl, buffer + start_offset, 0), 0);
1491 + else if (zero_count > 0)
1492 + for (int length_argument = 0;
1493 + length_argument <= 2 * buffer_length;
1494 + ++length_argument)
1496 + if (test_verbose)
1497 + printf ("zero_count=%d a_count=%d start_offset=%d"
1498 + " length_argument=%d\n",
1499 + zero_count, a_count, start_offset,
1500 + length_argument);
1501 + if (start_offset < a_count)
1502 + TEST_COMPARE (CALL (impl, start_pointer, length_argument),
1503 + MIN (a_count - start_offset,
1504 + length_argument));
1505 + else
1506 + TEST_COMPARE (CALL (impl, start_pointer, length_argument),
1507 + 0);
1509 + else
1510 + for (int length_argument = 0;
1511 + length_argument <= buffer_length - start_offset;
1512 + ++length_argument)
1513 + TEST_COMPARE (CALL (impl, start_pointer, length_argument),
1514 + length_argument);
1519 + support_next_to_fault_free (&ntf);
1521 + return 0;
1524 +#include <support/test-driver.c>
1525 diff --git a/string/test-strnlen-nonarray.c b/string/test-strnlen-nonarray.c
1526 new file mode 100644
1527 index 0000000000..0ad05756d9
1528 --- /dev/null
1529 +++ b/string/test-strnlen-nonarray.c
1530 @@ -0,0 +1,4 @@
1531 +#define TEST_IDENTIFIER strnlen
1532 +#define TEST_NAME "strnlen"
1533 +typedef char CHAR;
1534 +#include "test-Xnlen-nonarray.c"
1535 diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
1536 index 1cddd8cc6d..c51c9b4f1f 100644
1537 --- a/wcsmbs/Makefile
1538 +++ b/wcsmbs/Makefile
1539 @@ -160,6 +160,7 @@ tests := \
1540 test-wcsncmp \
1541 test-wcsncpy \
1542 test-wcsnlen \
1543 + test-wcsnlen-nonarray \
1544 test-wcspbrk \
1545 test-wcsrchr \
1546 test-wcsspn \
1547 diff --git a/wcsmbs/test-wcsnlen-nonarray.c b/wcsmbs/test-wcsnlen-nonarray.c
1548 new file mode 100644
1549 index 0000000000..a4b21fecd3
1550 --- /dev/null
1551 +++ b/wcsmbs/test-wcsnlen-nonarray.c
1552 @@ -0,0 +1,5 @@
1553 +#include <wchar.h>
1554 +#define TEST_IDENTIFIER wcsnlen
1555 +#define TEST_NAME "wcsnlen"
1556 +typedef wchar_t CHAR;
1557 +#include "../string/test-Xnlen-nonarray.c"
1559 commit 46f19b234244f4654b9e3898ac1c27de86068222
1560 Author: Florian Weimer <fweimer@redhat.com>
1561 Date: Thu Jun 27 16:26:56 2024 +0200
1563 Enhanced test coverage for strncmp, wcsncmp
1565 Add string/test-strncmp-nonarray and
1566 wcsmbs/test-wcsncmp-nonarray.
1568 This is the test that uncovered bug 31934. Test run time
1569 is more than one minute on a fairly current system, so turn
1570 these into xtests that do not run automatically.
1572 Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
1573 (cherry picked from commit 54252394c25ddf0062e288d4a6ab7a885f8ae009)
1575 diff --git a/string/Makefile b/string/Makefile
1576 index 2e20fc00fd..1dff405c27 100644
1577 --- a/string/Makefile
1578 +++ b/string/Makefile
1579 @@ -236,7 +236,10 @@ tests-unsupported += $(tests-translation)
1580 endif
1582 # This test allocates a lot of memory and can run for a long time.
1583 -xtests = tst-strcoll-overflow
1584 +xtests += tst-strcoll-overflow
1586 +# This test runs for a long time.
1587 +xtests += test-strncmp-nonarray
1589 # This test needs libdl.
1590 ifeq (yes,$(build-shared))
1591 diff --git a/string/test-Xncmp-nonarray.c b/string/test-Xncmp-nonarray.c
1592 new file mode 100644
1593 index 0000000000..9f3a3ca75d
1594 --- /dev/null
1595 +++ b/string/test-Xncmp-nonarray.c
1596 @@ -0,0 +1,183 @@
1597 +/* Test non-array inputs to string comparison functions.
1598 + Copyright (C) 2024 Free Software Foundation, Inc.
1599 + This file is part of the GNU C Library.
1601 + The GNU C Library is free software; you can redistribute it and/or
1602 + modify it under the terms of the GNU Lesser General Public
1603 + License as published by the Free Software Foundation; either
1604 + version 2.1 of the License, or (at your option) any later version.
1606 + The GNU C Library is distributed in the hope that it will be useful,
1607 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1608 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1609 + Lesser General Public License for more details.
1611 + You should have received a copy of the GNU Lesser General Public
1612 + License along with the GNU C Library; if not, see
1613 + <https://www.gnu.org/licenses/>. */
1615 +/* This skeleton file is included from string/test-strncmp-nonarray.c and
1616 + wcsmbs/test-wcsncmp-nonarray.c to test that reading of the arrays stops
1617 + at the first null character.
1619 + TEST_IDENTIFIER must be the test function identifier. TEST_NAME is
1620 + the same as a string.
1622 + CHAR must be defined as the character type. */
1624 +#include <array_length.h>
1625 +#include <string.h>
1626 +#include <support/check.h>
1627 +#include <support/next_to_fault.h>
1628 +#include <support/test-driver.h>
1629 +#include <sys/param.h>
1630 +#include <unistd.h>
1632 +/* Much shorter than test-Xnlen-nonarray.c because of deeply nested loops. */
1633 +enum { buffer_length = 80 };
1635 +/* The test buffer layout follows what is described test-Xnlen-nonarray.c,
1636 + except that there two buffers, left and right. The variables
1637 + a_count, zero_count, start_offset are all duplicated. */
1639 +/* Return the maximum string length for a string that starts at
1640 + start_offset. */
1641 +static int
1642 +string_length (int a_count, int start_offset)
1644 + if (start_offset == buffer_length || start_offset >= a_count)
1645 + return 0;
1646 + else
1647 + return a_count - start_offset;
1650 +/* This is the valid maximum length argument computation for
1651 + strnlen/wcsnlen. See text-Xnlen-nonarray.c. */
1652 +static int
1653 +maximum_length (int start_offset, int zero_count)
1655 + if (start_offset == buffer_length)
1656 + return 0;
1657 + else if (zero_count > 0)
1658 + /* Effectively unbounded, but we need to stop fairly low,
1659 + otherwise testing takes too long. */
1660 + return buffer_length + 32;
1661 + else
1662 + return buffer_length - start_offset;
1665 +typedef __typeof (TEST_IDENTIFIER) *proto_t;
1667 +#define TEST_MAIN
1668 +#include "test-string.h"
1670 +IMPL (TEST_IDENTIFIER, 1)
1672 +static int
1673 +test_main (void)
1675 + TEST_VERIFY_EXIT (sysconf (_SC_PAGESIZE) >= buffer_length);
1676 + test_init ();
1678 + struct support_next_to_fault left_ntf
1679 + = support_next_to_fault_allocate (buffer_length * sizeof (CHAR));
1680 + CHAR *left_buffer = (CHAR *) left_ntf.buffer;
1681 + struct support_next_to_fault right_ntf
1682 + = support_next_to_fault_allocate (buffer_length * sizeof (CHAR));
1683 + CHAR *right_buffer = (CHAR *) right_ntf.buffer;
1685 + FOR_EACH_IMPL (impl, 0)
1687 + printf ("info: testing %s\n", impl->name);
1688 + for (size_t i = 0; i < buffer_length; ++i)
1689 + left_buffer[i] = 'A';
1691 + for (int left_zero_count = 0; left_zero_count <= buffer_length;
1692 + ++left_zero_count)
1694 + if (left_zero_count > 0)
1695 + left_buffer[buffer_length - left_zero_count] = 0;
1696 + int left_a_count = buffer_length - left_zero_count;
1697 + for (size_t i = 0; i < buffer_length; ++i)
1698 + right_buffer[i] = 'A';
1699 + for (int right_zero_count = 0; right_zero_count <= buffer_length;
1700 + ++right_zero_count)
1702 + if (right_zero_count > 0)
1703 + right_buffer[buffer_length - right_zero_count] = 0;
1704 + int right_a_count = buffer_length - right_zero_count;
1705 + for (int left_start_offset = 0;
1706 + left_start_offset <= buffer_length;
1707 + ++left_start_offset)
1709 + CHAR *left_start_pointer = left_buffer + left_start_offset;
1710 + int left_maxlen
1711 + = maximum_length (left_start_offset, left_zero_count);
1712 + int left_length
1713 + = string_length (left_a_count, left_start_offset);
1714 + for (int right_start_offset = 0;
1715 + right_start_offset <= buffer_length;
1716 + ++right_start_offset)
1718 + CHAR *right_start_pointer
1719 + = right_buffer + right_start_offset;
1720 + int right_maxlen
1721 + = maximum_length (right_start_offset, right_zero_count);
1722 + int right_length
1723 + = string_length (right_a_count, right_start_offset);
1725 + /* Maximum length is modelled after strnlen/wcsnlen,
1726 + and must be valid for both pointer arguments at
1727 + the same time. */
1728 + int maxlen = MIN (left_maxlen, right_maxlen);
1730 + for (int length_argument = 0; length_argument <= maxlen;
1731 + ++length_argument)
1733 + if (test_verbose)
1735 + printf ("left: zero_count=%d"
1736 + " a_count=%d start_offset=%d\n",
1737 + left_zero_count, left_a_count,
1738 + left_start_offset);
1739 + printf ("right: zero_count=%d"
1740 + " a_count=%d start_offset=%d\n",
1741 + right_zero_count, right_a_count,
1742 + right_start_offset);
1743 + printf ("length argument: %d\n",
1744 + length_argument);
1747 + /* Effective lengths bounded by length argument.
1748 + The effective length determines the
1749 + outcome of the comparison. */
1750 + int left_effective
1751 + = MIN (left_length, length_argument);
1752 + int right_effective
1753 + = MIN (right_length, length_argument);
1754 + if (left_effective == right_effective)
1755 + TEST_COMPARE (CALL (impl,
1756 + left_start_pointer,
1757 + right_start_pointer,
1758 + length_argument), 0);
1759 + else if (left_effective < right_effective)
1760 + TEST_COMPARE (CALL (impl,
1761 + left_start_pointer,
1762 + right_start_pointer,
1763 + length_argument) < 0, 1);
1764 + else
1765 + TEST_COMPARE (CALL (impl,
1766 + left_start_pointer,
1767 + right_start_pointer,
1768 + length_argument) > 0, 1);
1776 + return 0;
1779 +#include <support/test-driver.c>
1780 diff --git a/string/test-strncmp-nonarray.c b/string/test-strncmp-nonarray.c
1781 new file mode 100644
1782 index 0000000000..581e52d01b
1783 --- /dev/null
1784 +++ b/string/test-strncmp-nonarray.c
1785 @@ -0,0 +1,4 @@
1786 +#define TEST_IDENTIFIER strncmp
1787 +#define TEST_NAME "strncmp"
1788 +typedef char CHAR;
1789 +#include "test-Xncmp-nonarray.c"
1790 diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
1791 index c51c9b4f1f..63adf0e8ef 100644
1792 --- a/wcsmbs/Makefile
1793 +++ b/wcsmbs/Makefile
1794 @@ -206,6 +206,10 @@ tests := \
1795 wcsmbs-tst1 \
1796 # tests
1798 +# This test runs for a long time.
1799 +xtests += test-wcsncmp-nonarray
1802 include ../Rules
1804 ifeq ($(run-built-tests),yes)
1805 diff --git a/wcsmbs/test-wcsncmp-nonarray.c b/wcsmbs/test-wcsncmp-nonarray.c
1806 new file mode 100644
1807 index 0000000000..1ad9ebd8fd
1808 --- /dev/null
1809 +++ b/wcsmbs/test-wcsncmp-nonarray.c
1810 @@ -0,0 +1,5 @@
1811 +#include <wchar.h>
1812 +#define TEST_IDENTIFIER wcsncmp
1813 +#define TEST_NAME "wcsncmp"
1814 +typedef wchar_t CHAR;
1815 +#include "../string/test-Xncmp-nonarray.c"
1817 commit 3433a358428bcec2d203fa408b85f442c9a465ca
1818 Author: H.J. Lu <hjl.tools@gmail.com>
1819 Date: Wed Jul 24 14:05:13 2024 -0700
1821 linux: Update the mremap C implementation [BZ #31968]
1823 Update the mremap C implementation to support the optional argument for
1824 MREMAP_DONTUNMAP added in Linux 5.7 since it may not always be correct
1825 to implement a variadic function as a non-variadic function on all Linux
1826 targets. Return MAP_FAILED and set errno to EINVAL for unknown flag bits.
1827 This fixes BZ #31968.
1829 Note: A test must be added when a new flag bit is introduced.
1831 Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
1832 Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
1833 (cherry picked from commit 6c40cb0e9f893d49dc7caee580a055de53562206)
1835 diff --git a/NEWS b/NEWS
1836 index 6b62f55658..5948704ef9 100644
1837 --- a/NEWS
1838 +++ b/NEWS
1839 @@ -11,6 +11,7 @@ The following bugs are resolved with this release:
1841 [30081] resolv: Do not wait for non-existing second DNS response after error
1842 [31890] resolv: Allow short error responses to match any DNS query
1843 + [31968] mremap implementation in C does not handle arguments correctly
1845 Version 2.40
1847 diff --git a/sysdeps/unix/sysv/linux/mremap.c b/sysdeps/unix/sysv/linux/mremap.c
1848 index 4f770799c4..1ada5c1f40 100644
1849 --- a/sysdeps/unix/sysv/linux/mremap.c
1850 +++ b/sysdeps/unix/sysv/linux/mremap.c
1851 @@ -20,6 +20,12 @@
1852 #include <sysdep.h>
1853 #include <stdarg.h>
1854 #include <stddef.h>
1855 +#include <errno.h>
1857 +#define MREMAP_KNOWN_BITS \
1858 + (MREMAP_MAYMOVE \
1859 + | MREMAP_FIXED \
1860 + | MREMAP_DONTUNMAP)
1862 void *
1863 __mremap (void *addr, size_t old_len, size_t new_len, int flags, ...)
1864 @@ -27,7 +33,13 @@ __mremap (void *addr, size_t old_len, size_t new_len, int flags, ...)
1865 va_list va;
1866 void *new_addr = NULL;
1868 - if (flags & MREMAP_FIXED)
1869 + if (flags & ~(MREMAP_KNOWN_BITS))
1871 + __set_errno (EINVAL);
1872 + return MAP_FAILED;
1875 + if (flags & (MREMAP_FIXED | MREMAP_DONTUNMAP))
1877 va_start (va, flags);
1878 new_addr = va_arg (va, void *);
1880 commit 2eb2d78ca75d7432bd1d11d227f4c899554ea02e
1881 Author: H.J. Lu <hjl.tools@gmail.com>
1882 Date: Wed Jul 24 14:05:14 2024 -0700
1884 mremap: Update manual entry
1886 Update mremap manual entry:
1888 1. Change mremap to variadic.
1889 2. Document MREMAP_FIXED and MREMAP_DONTUNMAP.
1891 Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
1892 Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
1893 (cherry picked from commit cb2dee4eccf46642eef588bee64f9c875c408f1c)
1895 diff --git a/NEWS b/NEWS
1896 index 5948704ef9..8da0408ad9 100644
1897 --- a/NEWS
1898 +++ b/NEWS
1899 @@ -10,6 +10,7 @@ Version 2.40.1
1900 The following bugs are resolved with this release:
1902 [30081] resolv: Do not wait for non-existing second DNS response after error
1903 + [31968] mremap implementation in C does not handle arguments correctly
1904 [31890] resolv: Allow short error responses to match any DNS query
1905 [31968] mremap implementation in C does not handle arguments correctly
1907 diff --git a/manual/llio.texi b/manual/llio.texi
1908 index 6f0a48609b..ea84196abd 100644
1909 --- a/manual/llio.texi
1910 +++ b/manual/llio.texi
1911 @@ -1892,7 +1892,7 @@ There is no existing mapping in at least part of the given region.
1913 @end deftypefun
1915 -@deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag})
1916 +@deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag}, ... /* void *@var{new_address} */)
1917 @standards{GNU, sys/mman.h}
1918 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
1920 @@ -1901,12 +1901,40 @@ area. @var{address} and @var{length} must cover a region entirely mapped
1921 in the same @code{mmap} statement. A new mapping with the same
1922 characteristics will be returned with the length @var{new_length}.
1924 -One option is possible, @code{MREMAP_MAYMOVE}. If it is given in
1925 -@var{flags}, the system may remove the existing mapping and create a new
1926 -one of the desired length in another location.
1927 +Possible flags are
1929 -The address of the resulting mapping is returned, or @math{-1}. Possible
1930 -error codes include:
1931 +@table @code
1933 +@item MREMAP_MAYMOVE
1934 +If it is given in @var{flags}, the system may remove the existing mapping
1935 +and create a new one of the desired length in another location.
1937 +@item MREMAP_FIXED
1938 +If it is given in @var{flags}, @code{mremap} accepts a fifth argument,
1939 +@code{void *new_address}, which specifies a page-aligned address to
1940 +which the mapping must be moved. Any previous mapping at the address
1941 +range specified by @var{new_address} and @var{new_size} is unmapped.
1943 +@code{MREMAP_FIXED} must be used together with @code{MREMAP_MAYMOVE}.
1945 +@item MREMAP_DONTUNMAP
1946 +If it is given in @var{flags}, @code{mremap} accepts a fifth argument,
1947 +@code{void *new_address}, which specifies a page-aligned address. Any
1948 +previous mapping at the address range specified by @var{new_address} and
1949 +@var{new_size} is unmapped. If @var{new_address} is @code{NULL}, the
1950 +kernel chooses the page-aligned address at which to create the mapping.
1951 +Otherwise, the kernel takes it as a hint about where to place the mapping.
1952 +The mapping at the address range specified by @var{old_address} and
1953 +@var{old_size} isn't unmapped.
1955 +@code{MREMAP_DONTUNMAP} must be used together with @code{MREMAP_MAYMOVE}.
1956 +@var{old_size} must be the same as @var{new_size}. This flag bit is
1957 +Linux-specific.
1959 +@end table
1961 +The address of the resulting mapping is returned, or @code{MAP_FAILED}.
1962 +Possible error codes include:
1964 @table @code
1966 @@ -1915,7 +1943,7 @@ There is no existing mapping in at least part of the original region, or
1967 the region covers two or more distinct mappings.
1969 @item EINVAL
1970 -The address given is misaligned or inappropriate.
1971 +Any arguments are inappropriate, including unknown @var{flags} values.
1973 @item EAGAIN
1974 The region has pages locked, and if extended it would exceed the
1976 commit ca53bc68ab92ab413a7d53e951227d380a85ebd8
1977 Author: H.J. Lu <hjl.tools@gmail.com>
1978 Date: Wed Jul 24 14:05:15 2024 -0700
1980 Add mremap tests
1982 Add tests for MREMAP_MAYMOVE and MREMAP_FIXED. On Linux, also test
1983 MREMAP_DONTUNMAP.
1985 Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
1986 Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
1987 (cherry picked from commit ff0320bec2810192d453c579623482fab87bfa01)
1989 diff --git a/misc/Makefile b/misc/Makefile
1990 index 5d17c562fe..7b7f8351bf 100644
1991 --- a/misc/Makefile
1992 +++ b/misc/Makefile
1993 @@ -257,6 +257,8 @@ tests := \
1994 tst-mntent-blank-passno \
1995 tst-mntent-escape \
1996 tst-mntent2 \
1997 + tst-mremap1 \
1998 + tst-mremap2 \
1999 tst-preadvwritev \
2000 tst-preadvwritev2 \
2001 tst-preadvwritev64 \
2002 diff --git a/misc/tst-mremap1.c b/misc/tst-mremap1.c
2003 new file mode 100644
2004 index 0000000000..0469991a6c
2005 --- /dev/null
2006 +++ b/misc/tst-mremap1.c
2007 @@ -0,0 +1,46 @@
2008 +/* Test mremap with MREMAP_MAYMOVE.
2009 + Copyright (C) 2024 Free Software Foundation, Inc.
2010 + This file is part of the GNU C Library.
2012 + The GNU C Library is free software; you can redistribute it and/or
2013 + modify it under the terms of the GNU Lesser General Public
2014 + License as published by the Free Software Foundation; either
2015 + version 2.1 of the License, or (at your option) any later version.
2017 + The GNU C Library is distributed in the hope that it will be useful,
2018 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2019 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2020 + Lesser General Public License for more details.
2022 + You should have received a copy of the GNU Lesser General Public
2023 + License along with the GNU C Library; if not, see
2024 + <https://www.gnu.org/licenses/>. */
2026 +#include <errno.h>
2027 +#include <sys/mman.h>
2028 +#include <support/xstdlib.h>
2029 +#include <support/xunistd.h>
2030 +#include <support/check.h>
2031 +#include <support/test-driver.h>
2033 +static int
2034 +do_test (void)
2036 + size_t old_size = getpagesize ();
2037 + char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE,
2038 + MAP_PRIVATE | MAP_ANONYMOUS, -1);
2039 + old_addr[0] = 1;
2040 + old_addr[old_size - 1] = 2;
2042 + /* Test MREMAP_MAYMOVE. */
2043 + size_t new_size = old_size + old_size;
2044 + char *new_addr = mremap (old_addr, old_size, new_size, MREMAP_MAYMOVE);
2045 + TEST_VERIFY_EXIT (new_addr != MAP_FAILED);
2046 + new_addr[0] = 1;
2047 + new_addr[new_size - 1] = 2;
2048 + xmunmap (new_addr, new_size);
2050 + return 0;
2053 +#include <support/test-driver.c>
2054 diff --git a/misc/tst-mremap2.c b/misc/tst-mremap2.c
2055 new file mode 100644
2056 index 0000000000..45be7f0369
2057 --- /dev/null
2058 +++ b/misc/tst-mremap2.c
2059 @@ -0,0 +1,54 @@
2060 +/* Test mremap with MREMAP_FIXED.
2061 + Copyright (C) 2024 Free Software Foundation, Inc.
2062 + This file is part of the GNU C Library.
2064 + The GNU C Library is free software; you can redistribute it and/or
2065 + modify it under the terms of the GNU Lesser General Public
2066 + License as published by the Free Software Foundation; either
2067 + version 2.1 of the License, or (at your option) any later version.
2069 + The GNU C Library is distributed in the hope that it will be useful,
2070 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2071 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2072 + Lesser General Public License for more details.
2074 + You should have received a copy of the GNU Lesser General Public
2075 + License along with the GNU C Library; if not, see
2076 + <https://www.gnu.org/licenses/>. */
2078 +#include <errno.h>
2079 +#include <sys/mman.h>
2080 +#include <support/xstdlib.h>
2081 +#include <support/xunistd.h>
2082 +#include <support/test-driver.h>
2083 +#include <mremap-failure.h>
2085 +static int
2086 +do_test (void)
2088 + size_t old_size = getpagesize ();
2089 + size_t new_size = old_size + old_size;
2090 + char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE,
2091 + MAP_PRIVATE | MAP_ANONYMOUS, -1);
2092 + old_addr[0] = 1;
2093 + old_addr[old_size - 1] = 2;
2095 + char *fixed_addr = xmmap (NULL, new_size, PROT_READ | PROT_WRITE,
2096 + MAP_PRIVATE | MAP_ANONYMOUS, -1);
2097 + fixed_addr[0] = 1;
2098 + fixed_addr[new_size - 1] = 2;
2100 + /* Test MREMAP_FIXED. */
2101 + char *new_addr = mremap (old_addr, old_size, new_size,
2102 + MREMAP_FIXED | MREMAP_MAYMOVE,
2103 + fixed_addr);
2104 + if (new_addr == MAP_FAILED)
2105 + return mremap_failure_exit (errno);
2106 + new_addr[0] = 1;
2107 + new_addr[new_size - 1] = 2;
2108 + xmunmap (new_addr, new_size);
2110 + return 0;
2113 +#include <support/test-driver.c>
2114 diff --git a/sysdeps/generic/mremap-failure.h b/sysdeps/generic/mremap-failure.h
2115 new file mode 100644
2116 index 0000000000..bc0d476368
2117 --- /dev/null
2118 +++ b/sysdeps/generic/mremap-failure.h
2119 @@ -0,0 +1,25 @@
2120 +/* mremap failure handling. Generic version.
2121 + Copyright (C) 2024 Free Software Foundation, Inc.
2122 + This file is part of the GNU C Library.
2124 + The GNU C Library is free software; you can redistribute it and/or
2125 + modify it under the terms of the GNU Lesser General Public
2126 + License as published by the Free Software Foundation; either
2127 + version 2.1 of the License, or (at your option) any later version.
2129 + The GNU C Library is distributed in the hope that it will be useful,
2130 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2131 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2132 + Lesser General Public License for more details.
2134 + You should have received a copy of the GNU Lesser General Public
2135 + License along with the GNU C Library; if not, see
2136 + <https://www.gnu.org/licenses/>. */
2138 +/* Return exit value on mremap failure with errno ERR. */
2140 +static int
2141 +mremap_failure_exit (int err)
2143 + return EXIT_FAILURE;
2145 diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
2146 index 097b5a26fc..59998c7af4 100644
2147 --- a/sysdeps/unix/sysv/linux/Makefile
2148 +++ b/sysdeps/unix/sysv/linux/Makefile
2149 @@ -206,6 +206,7 @@ tests += \
2150 tst-getauxval \
2151 tst-gettid \
2152 tst-gettid-kill \
2153 + tst-linux-mremap1 \
2154 tst-memfd_create \
2155 tst-misalign-clone \
2156 tst-mlock2 \
2157 diff --git a/sysdeps/unix/sysv/linux/mremap-failure.h b/sysdeps/unix/sysv/linux/mremap-failure.h
2158 new file mode 100644
2159 index 0000000000..c99ab30ca9
2160 --- /dev/null
2161 +++ b/sysdeps/unix/sysv/linux/mremap-failure.h
2162 @@ -0,0 +1,30 @@
2163 +/* mremap failure handling. Linux version.
2164 + Copyright (C) 2024 Free Software Foundation, Inc.
2165 + This file is part of the GNU C Library.
2167 + The GNU C Library is free software; you can redistribute it and/or
2168 + modify it under the terms of the GNU Lesser General Public
2169 + License as published by the Free Software Foundation; either
2170 + version 2.1 of the License, or (at your option) any later version.
2172 + The GNU C Library is distributed in the hope that it will be useful,
2173 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2174 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2175 + Lesser General Public License for more details.
2177 + You should have received a copy of the GNU Lesser General Public
2178 + License along with the GNU C Library; if not, see
2179 + <https://www.gnu.org/licenses/>. */
2181 +#include <support/check.h>
2183 +/* Return exit value on mremap failure with errno ERR. */
2185 +static int
2186 +mremap_failure_exit (int err)
2188 + if (err != EINVAL)
2189 + return EXIT_FAILURE;
2191 + return EXIT_UNSUPPORTED;
2193 diff --git a/sysdeps/unix/sysv/linux/tst-linux-mremap1.c b/sysdeps/unix/sysv/linux/tst-linux-mremap1.c
2194 new file mode 100644
2195 index 0000000000..408e8af2ab
2196 --- /dev/null
2197 +++ b/sysdeps/unix/sysv/linux/tst-linux-mremap1.c
2198 @@ -0,0 +1,63 @@
2199 +/* Test mremap with MREMAP_DONTUNMAP.
2200 + Copyright (C) 2024 Free Software Foundation, Inc.
2201 + This file is part of the GNU C Library.
2203 + The GNU C Library is free software; you can redistribute it and/or
2204 + modify it under the terms of the GNU Lesser General Public
2205 + License as published by the Free Software Foundation; either
2206 + version 2.1 of the License, or (at your option) any later version.
2208 + The GNU C Library is distributed in the hope that it will be useful,
2209 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2210 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2211 + Lesser General Public License for more details.
2213 + You should have received a copy of the GNU Lesser General Public
2214 + License along with the GNU C Library; if not, see
2215 + <https://www.gnu.org/licenses/>. */
2217 +#include <errno.h>
2218 +#include <sys/mman.h>
2219 +#include <support/xstdlib.h>
2220 +#include <support/xunistd.h>
2221 +#include <support/check.h>
2222 +#include <support/test-driver.h>
2223 +#include <mremap-failure.h>
2225 +static int
2226 +do_test (void)
2228 + size_t old_size = getpagesize ();
2229 + size_t new_size = old_size;
2230 + char *old_addr = xmmap (NULL, old_size, PROT_READ | PROT_WRITE,
2231 + MAP_PRIVATE | MAP_ANONYMOUS, -1);
2232 + old_addr[0] = 1;
2233 + old_addr[old_size - 1] = 2;
2235 + /* Create an available 64-page mmap region. */
2236 + size_t fixed_size = old_size * 64;
2237 + char *fixed_addr = xmmap (NULL, fixed_size, PROT_READ | PROT_WRITE,
2238 + MAP_PRIVATE | MAP_ANONYMOUS, -1);
2239 + xmunmap (fixed_addr, fixed_size);
2241 + /* Add 3 * pagesize. */
2242 + fixed_size += 3 * old_size;
2244 + /* Test MREMAP_DONTUNMAP. It should return FIXED_ADDR created above. */
2245 + char *new_addr = mremap (old_addr, old_size, new_size,
2246 + MREMAP_DONTUNMAP | MREMAP_MAYMOVE,
2247 + fixed_addr);
2248 + if (new_addr == MAP_FAILED)
2249 + return mremap_failure_exit (errno);
2250 + TEST_VERIFY_EXIT (fixed_addr == new_addr);
2251 + old_addr[0] = 3;
2252 + old_addr[old_size - 1] = 4;
2253 + new_addr[0] = 1;
2254 + new_addr[new_size - 1] = 2;
2255 + xmunmap (new_addr, new_size);
2256 + xmunmap (old_addr, old_size);
2258 + return 0;
2261 +#include <support/test-driver.c>
2263 commit 928769737c8f0cbb51dfa2a02de0594c2395d802
2264 Author: Florian Weimer <fweimer@redhat.com>
2265 Date: Thu Aug 1 10:46:10 2024 +0200
2267 resolv: Fix tst-resolv-short-response for older GCC (bug 32042)
2269 Previous GCC versions do not support the C23 change that
2270 allows labels on declarations.
2272 Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2273 (cherry picked from commit ec119972cb2598c04ec7d4219e20506006836f64)
2275 diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c
2276 index be354ae1c7..9b06b0c176 100644
2277 --- a/resolv/tst-resolv-short-response.c
2278 +++ b/resolv/tst-resolv-short-response.c
2279 @@ -33,8 +33,10 @@ response (const struct resolv_response_context *ctx,
2281 case 0:
2282 /* First server times out. */
2283 - struct resolv_response_flags flags = {.rcode = rcode};
2284 - resolv_response_init (b, flags);
2286 + struct resolv_response_flags flags = {.rcode = rcode};
2287 + resolv_response_init (b, flags);
2289 break;
2290 case 1:
2291 /* Second server sends reply. */
2293 commit aa533d58ff12e27771d9c960a727d74992a3f2a3
2294 Author: Florian Weimer <fweimer@redhat.com>
2295 Date: Fri Aug 2 15:22:14 2024 +0200
2297 x86: Tunables may incorrectly set Prefer_PMINUB_for_stringop (bug 32047)
2299 Fixes commit 5bcf6265f215326d14dfacdce8532792c2c7f8f8 ("x86:
2300 Disable non-temporal memset on Skylake Server").
2302 Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
2303 (cherry picked from commit 7a630f7d3392ca391a399486ce2846f9e4b4ee63)
2305 diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
2306 index ae9dcd6180..ccc6b64dc2 100644
2307 --- a/sysdeps/x86/cpu-tunables.c
2308 +++ b/sysdeps/x86/cpu-tunables.c
2309 @@ -248,6 +248,7 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
2310 CHECK_GLIBC_IFUNC_PREFERRED_BOTH (n, cpu_features,
2311 Avoid_Non_Temporal_Memset, 25);
2313 + break;
2314 case 26:
2316 CHECK_GLIBC_IFUNC_PREFERRED_NEED_BOTH
2318 commit 6a97e2ba144a554809161d488f25e4bae07c9405
2319 Author: Andreas Schwab <schwab@suse.de>
2320 Date: Mon Aug 5 10:55:51 2024 +0200
2322 Fix name space violation in fortify wrappers (bug 32052)
2324 Rename the identifier sz to __sz everywhere.
2326 Fixes: a643f60c53 ("Make sure that the fortified function conditionals are constant")
2327 (cherry picked from commit 39ca997ab378990d5ac1aadbaa52aaf1db6d526f)
2329 diff --git a/NEWS b/NEWS
2330 index 8da0408ad9..b9eb4a558b 100644
2331 --- a/NEWS
2332 +++ b/NEWS
2333 @@ -13,6 +13,7 @@ The following bugs are resolved with this release:
2334 [31968] mremap implementation in C does not handle arguments correctly
2335 [31890] resolv: Allow short error responses to match any DNS query
2336 [31968] mremap implementation in C does not handle arguments correctly
2337 + [32052] Name space violation in fortify wrappers
2339 Version 2.40
2341 diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
2342 index 91a80dd7c6..4b8bc35bdf 100644
2343 --- a/libio/bits/stdio2.h
2344 +++ b/libio/bits/stdio2.h
2345 @@ -308,14 +308,14 @@ fgets (__fortify_clang_overload_arg (char *, __restrict, __s), int __n,
2346 "fgets called with bigger size than length of "
2347 "destination buffer")
2349 - size_t sz = __glibc_objsize (__s);
2350 - if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
2351 + size_t __sz = __glibc_objsize (__s);
2352 + if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
2353 return __fgets_alias (__s, __n, __stream);
2354 #if !__fortify_use_clang
2355 - if (__glibc_unsafe_len (__n, sizeof (char), sz))
2356 - return __fgets_chk_warn (__s, sz, __n, __stream);
2357 + if (__glibc_unsafe_len (__n, sizeof (char), __sz))
2358 + return __fgets_chk_warn (__s, __sz, __n, __stream);
2359 #endif
2360 - return __fgets_chk (__s, sz, __n, __stream);
2361 + return __fgets_chk (__s, __sz, __n, __stream);
2364 __fortify_function __wur __nonnull ((4)) __attribute_overloadable__ size_t
2365 @@ -326,14 +326,14 @@ fread (__fortify_clang_overload_arg (void *, __restrict, __ptr),
2366 "fread called with bigger size * n than length "
2367 "of destination buffer")
2369 - size_t sz = __glibc_objsize0 (__ptr);
2370 - if (__glibc_safe_or_unknown_len (__n, __size, sz))
2371 + size_t __sz = __glibc_objsize0 (__ptr);
2372 + if (__glibc_safe_or_unknown_len (__n, __size, __sz))
2373 return __fread_alias (__ptr, __size, __n, __stream);
2374 #if !__fortify_use_clang
2375 - if (__glibc_unsafe_len (__n, __size, sz))
2376 - return __fread_chk_warn (__ptr, sz, __size, __n, __stream);
2377 + if (__glibc_unsafe_len (__n, __size, __sz))
2378 + return __fread_chk_warn (__ptr, __sz, __size, __n, __stream);
2379 #endif
2380 - return __fread_chk (__ptr, sz, __size, __n, __stream);
2381 + return __fread_chk (__ptr, __sz, __size, __n, __stream);
2384 #ifdef __USE_GNU
2385 @@ -345,14 +345,14 @@ fgets_unlocked (__fortify_clang_overload_arg (char *, __restrict, __s),
2386 "fgets called with bigger size than length of "
2387 "destination buffer")
2389 - size_t sz = __glibc_objsize (__s);
2390 - if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
2391 + size_t __sz = __glibc_objsize (__s);
2392 + if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
2393 return __fgets_unlocked_alias (__s, __n, __stream);
2394 #if !__fortify_use_clang
2395 - if (__glibc_unsafe_len (__n, sizeof (char), sz))
2396 - return __fgets_unlocked_chk_warn (__s, sz, __n, __stream);
2397 + if (__glibc_unsafe_len (__n, sizeof (char), __sz))
2398 + return __fgets_unlocked_chk_warn (__s, __sz, __n, __stream);
2399 #endif
2400 - return __fgets_unlocked_chk (__s, sz, __n, __stream);
2401 + return __fgets_unlocked_chk (__s, __sz, __n, __stream);
2403 #endif
2405 @@ -366,8 +366,8 @@ fread_unlocked (__fortify_clang_overload_arg0 (void *, __restrict, __ptr),
2406 "fread_unlocked called with bigger size * n than "
2407 "length of destination buffer")
2409 - size_t sz = __glibc_objsize0 (__ptr);
2410 - if (__glibc_safe_or_unknown_len (__n, __size, sz))
2411 + size_t __sz = __glibc_objsize0 (__ptr);
2412 + if (__glibc_safe_or_unknown_len (__n, __size, __sz))
2414 # ifdef __USE_EXTERN_INLINES
2415 if (__builtin_constant_p (__size)
2416 @@ -393,10 +393,10 @@ fread_unlocked (__fortify_clang_overload_arg0 (void *, __restrict, __ptr),
2417 return __fread_unlocked_alias (__ptr, __size, __n, __stream);
2419 # if !__fortify_use_clang
2420 - if (__glibc_unsafe_len (__n, __size, sz))
2421 - return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream);
2422 + if (__glibc_unsafe_len (__n, __size, __sz))
2423 + return __fread_unlocked_chk_warn (__ptr, __sz, __size, __n, __stream);
2424 # endif
2425 - return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream);
2426 + return __fread_unlocked_chk (__ptr, __sz, __size, __n, __stream);
2429 #endif
2430 diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h
2431 index 04780f320e..bd91647f37 100644
2432 --- a/socket/bits/socket2.h
2433 +++ b/socket/bits/socket2.h
2434 @@ -37,14 +37,14 @@ recv (int __fd, __fortify_clang_overload_arg0 (void *, ,__buf), size_t __n,
2435 "recv called with bigger length than "
2436 "size of destination buffer")
2438 - size_t sz = __glibc_objsize0 (__buf);
2439 - if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
2440 + size_t __sz = __glibc_objsize0 (__buf);
2441 + if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
2442 return __recv_alias (__fd, __buf, __n, __flags);
2443 #if !__fortify_use_clang
2444 - if (__glibc_unsafe_len (__n, sizeof (char), sz))
2445 - return __recv_chk_warn (__fd, __buf, __n, sz, __flags);
2446 + if (__glibc_unsafe_len (__n, sizeof (char), __sz))
2447 + return __recv_chk_warn (__fd, __buf, __n, __sz, __flags);
2448 #endif
2449 - return __recv_chk (__fd, __buf, __n, sz, __flags);
2450 + return __recv_chk (__fd, __buf, __n, __sz, __flags);
2453 extern ssize_t __recvfrom_chk (int __fd, void *__restrict __buf, size_t __n,
2454 @@ -71,13 +71,13 @@ recvfrom (int __fd, __fortify_clang_overload_arg0 (void *, __restrict, __buf),
2455 "recvfrom called with bigger length "
2456 "than size of destination buffer")
2458 - size_t sz = __glibc_objsize0 (__buf);
2459 - if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz))
2460 + size_t __sz = __glibc_objsize0 (__buf);
2461 + if (__glibc_safe_or_unknown_len (__n, sizeof (char), __sz))
2462 return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len);
2463 #if !__fortify_use_clang
2464 - if (__glibc_unsafe_len (__n, sizeof (char), sz))
2465 - return __recvfrom_chk_warn (__fd, __buf, __n, sz, __flags, __addr,
2466 + if (__glibc_unsafe_len (__n, sizeof (char), __sz))
2467 + return __recvfrom_chk_warn (__fd, __buf, __n, __sz, __flags, __addr,
2468 __addr_len);
2469 #endif
2470 - return __recvfrom_chk (__fd, __buf, __n, sz, __flags, __addr, __addr_len);
2471 + return __recvfrom_chk (__fd, __buf, __n, __sz, __flags, __addr, __addr_len);
2473 diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
2474 index 1557b862b1..9c78ecf458 100644
2475 --- a/stdlib/bits/stdlib.h
2476 +++ b/stdlib/bits/stdlib.h
2477 @@ -43,16 +43,16 @@ __NTH (realpath (const char *__restrict __name,
2478 "bytes long buffer")
2479 #endif
2481 - size_t sz = __glibc_objsize (__resolved);
2482 + size_t __sz = __glibc_objsize (__resolved);
2484 - if (sz == (size_t) -1)
2485 + if (__sz == (size_t) -1)
2486 return __realpath_alias (__name, __resolved);
2488 #if !__fortify_use_clang && defined _LIBC_LIMITS_H_ && defined PATH_MAX
2489 - if (__glibc_unsafe_len (PATH_MAX, sizeof (char), sz))
2490 - return __realpath_chk_warn (__name, __resolved, sz);
2491 + if (__glibc_unsafe_len (PATH_MAX, sizeof (char), __sz))
2492 + return __realpath_chk_warn (__name, __resolved, __sz);
2493 #endif
2494 - return __realpath_chk (__name, __resolved, sz);
2495 + return __realpath_chk (__name, __resolved, __sz);
2499 diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
2500 index 9fdff47ee2..43c6b63027 100644
2501 --- a/wcsmbs/bits/wchar2.h
2502 +++ b/wcsmbs/bits/wchar2.h
2503 @@ -74,9 +74,9 @@ __fortify_function __attribute_overloadable__ wchar_t *
2504 __NTH (wcscpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest),
2505 const wchar_t *__restrict __src))
2507 - size_t sz = __glibc_objsize (__dest);
2508 - if (sz != (size_t) -1)
2509 - return __wcscpy_chk (__dest, __src, sz / sizeof (wchar_t));
2510 + size_t __sz = __glibc_objsize (__dest);
2511 + if (__sz != (size_t) -1)
2512 + return __wcscpy_chk (__dest, __src, __sz / sizeof (wchar_t));
2513 return __wcscpy_alias (__dest, __src);
2516 @@ -84,9 +84,9 @@ __fortify_function __attribute_overloadable__ wchar_t *
2517 __NTH (wcpcpy (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest),
2518 const wchar_t *__restrict __src))
2520 - size_t sz = __glibc_objsize (__dest);
2521 - if (sz != (size_t) -1)
2522 - return __wcpcpy_chk (__dest, __src, sz / sizeof (wchar_t));
2523 + size_t __sz = __glibc_objsize (__dest);
2524 + if (__sz != (size_t) -1)
2525 + return __wcpcpy_chk (__dest, __src, __sz / sizeof (wchar_t));
2526 return __wcpcpy_alias (__dest, __src);
2529 @@ -118,9 +118,9 @@ __fortify_function __attribute_overloadable__ wchar_t *
2530 __NTH (wcscat (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest),
2531 const wchar_t *__restrict __src))
2533 - size_t sz = __glibc_objsize (__dest);
2534 - if (sz != (size_t) -1)
2535 - return __wcscat_chk (__dest, __src, sz / sizeof (wchar_t));
2536 + size_t __sz = __glibc_objsize (__dest);
2537 + if (__sz != (size_t) -1)
2538 + return __wcscat_chk (__dest, __src, __sz / sizeof (wchar_t));
2539 return __wcscat_alias (__dest, __src);
2542 @@ -128,9 +128,9 @@ __fortify_function __attribute_overloadable__ wchar_t *
2543 __NTH (wcsncat (__fortify_clang_overload_arg (wchar_t *, __restrict, __dest),
2544 const wchar_t *__restrict __src, size_t __n))
2546 - size_t sz = __glibc_objsize (__dest);
2547 - if (sz != (size_t) -1)
2548 - return __wcsncat_chk (__dest, __src, __n, sz / sizeof (wchar_t));
2549 + size_t __sz = __glibc_objsize (__dest);
2550 + if (__sz != (size_t) -1)
2551 + return __wcsncat_chk (__dest, __src, __n, __sz / sizeof (wchar_t));
2552 return __wcsncat_alias (__dest, __src, __n);
2555 @@ -170,10 +170,10 @@ __fortify_function int
2556 __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
2557 const wchar_t *__restrict __fmt, ...))
2559 - size_t sz = __glibc_objsize (__s);
2560 - if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
2561 + size_t __sz = __glibc_objsize (__s);
2562 + if (__sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
2563 return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
2564 - sz / sizeof (wchar_t), __fmt, __va_arg_pack ());
2565 + __sz / sizeof (wchar_t), __fmt, __va_arg_pack ());
2566 return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
2568 #elif __fortify_use_clang
2569 @@ -206,10 +206,10 @@ __fortify_function int
2570 __NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
2571 const wchar_t *__restrict __fmt, __gnuc_va_list __ap))
2573 - size_t sz = __glibc_objsize (__s);
2574 - if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
2575 + size_t __sz = __glibc_objsize (__s);
2576 + if (__sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
2577 return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
2578 - sz / sizeof (wchar_t), __fmt, __ap);
2579 + __sz / sizeof (wchar_t), __fmt, __ap);
2580 return __vswprintf_alias (__s, __n, __fmt, __ap);
2583 @@ -257,14 +257,14 @@ fgetws (__fortify_clang_overload_arg (wchar_t *, __restrict, __s), int __n,
2584 "fgetws called with length bigger "
2585 "than size of destination buffer")
2587 - size_t sz = __glibc_objsize (__s);
2588 - if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz))
2589 + size_t __sz = __glibc_objsize (__s);
2590 + if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), __sz))
2591 return __fgetws_alias (__s, __n, __stream);
2592 #if !__fortify_use_clang
2593 - if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz))
2594 - return __fgetws_chk_warn (__s, sz / sizeof (wchar_t), __n, __stream);
2595 + if (__glibc_unsafe_len (__n, sizeof (wchar_t), __sz))
2596 + return __fgetws_chk_warn (__s, __sz / sizeof (wchar_t), __n, __stream);
2597 #endif
2598 - return __fgetws_chk (__s, sz / sizeof (wchar_t), __n, __stream);
2599 + return __fgetws_chk (__s, __sz / sizeof (wchar_t), __n, __stream);
2602 #ifdef __USE_GNU
2603 @@ -275,15 +275,15 @@ fgetws_unlocked (__fortify_clang_overload_arg (wchar_t *, __restrict, __s),
2604 "fgetws_unlocked called with length bigger "
2605 "than size of destination buffer")
2607 - size_t sz = __glibc_objsize (__s);
2608 - if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz))
2609 + size_t __sz = __glibc_objsize (__s);
2610 + if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), __sz))
2611 return __fgetws_unlocked_alias (__s, __n, __stream);
2612 # if !__fortify_use_clang
2613 - if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz))
2614 - return __fgetws_unlocked_chk_warn (__s, sz / sizeof (wchar_t), __n,
2615 + if (__glibc_unsafe_len (__n, sizeof (wchar_t), __sz))
2616 + return __fgetws_unlocked_chk_warn (__s, __sz / sizeof (wchar_t), __n,
2617 __stream);
2618 # endif
2619 - return __fgetws_unlocked_chk (__s, sz / sizeof (wchar_t), __n, __stream);
2620 + return __fgetws_unlocked_chk (__s, __sz / sizeof (wchar_t), __n, __stream);
2622 #endif
2625 commit 5641780762723156b0d20a0b9f7df1d76831bab0
2626 Author: Arjun Shankar <arjun@redhat.com>
2627 Date: Tue Jul 30 11:37:57 2024 +0200
2629 manual/stdio: Further clarify putc, putwc, getc, and getwc
2631 This is a follow-up to 10de4a47ef3f481592e3c62eb07bcda23e9fde4d that
2632 reworded the manual entries for putc and putwc and removed any
2633 performance claims.
2635 This commit further clarifies these entries and brings getc and getwc in
2636 line with the descriptions of putc and putwc, removing any performance
2637 claims from them as well.
2638 Reviewed-by: Florian Weimer <fweimer@redhat.com>
2640 (cherry picked from commit 942670c81dc8071dd75d6213e771daa5d2084cb6)
2642 diff --git a/manual/stdio.texi b/manual/stdio.texi
2643 index f9529a098d..8517653507 100644
2644 --- a/manual/stdio.texi
2645 +++ b/manual/stdio.texi
2646 @@ -904,20 +904,16 @@ This function is a GNU extension.
2647 @standards{ISO, stdio.h}
2648 @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
2649 This is just like @code{fputc}, except that it may be implemented as
2650 -a macro, making it faster. One consequence is that it may evaluate the
2651 -@var{stream} argument more than once, which is an exception to the
2652 -general rule for macros. Therefore, @var{stream} should never be an
2653 -expression with side-effects.
2654 +a macro and may evaluate the @var{stream} argument more than once.
2655 +Therefore, @var{stream} should never be an expression with side-effects.
2656 @end deftypefun
2658 @deftypefun wint_t putwc (wchar_t @var{wc}, FILE *@var{stream})
2659 @standards{ISO, wchar.h}
2660 @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
2661 This is just like @code{fputwc}, except that it may be implemented as
2662 -a macro, making it faster. One consequence is that it may evaluate the
2663 -@var{stream} argument more than once, which is an exception to the
2664 -general rule for macros. Therefore, @var{stream} should never be an
2665 -expression with side-effects.
2666 +a macro and may evaluate the @var{stream} argument more than once.
2667 +Therefore, @var{stream} should never be an expression with side-effects.
2668 @end deftypefun
2670 @deftypefun int putc_unlocked (int @var{c}, FILE *@var{stream})
2671 @@ -1110,20 +1106,17 @@ This function is a GNU extension.
2672 @deftypefun int getc (FILE *@var{stream})
2673 @standards{ISO, stdio.h}
2674 @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
2675 -This is just like @code{fgetc}, except that it is permissible (and
2676 -typical) for it to be implemented as a macro that evaluates the
2677 -@var{stream} argument more than once. @code{getc} is often highly
2678 -optimized, so it is usually the best function to use to read a single
2679 -character.
2680 +This is just like @code{fgetc}, except that it may be implemented as
2681 +a macro and may evaluate the @var{stream} argument more than once.
2682 +Therefore, @var{stream} should never be an expression with side-effects.
2683 @end deftypefun
2685 @deftypefun wint_t getwc (FILE *@var{stream})
2686 @standards{ISO, wchar.h}
2687 @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
2688 -This is just like @code{fgetwc}, except that it is permissible for it to
2689 -be implemented as a macro that evaluates the @var{stream} argument more
2690 -than once. @code{getwc} can be highly optimized, so it is usually the
2691 -best function to use to read a single wide character.
2692 +This is just like @code{fgetwc}, except that it may be implemented as
2693 +a macro and may evaluate the @var{stream} argument more than once.
2694 +Therefore, @var{stream} should never be an expression with side-effects.
2695 @end deftypefun
2697 @deftypefun int getc_unlocked (FILE *@var{stream})
2699 commit 39ee60a719eb6ffde76ccc232d79273c473d7a93
2700 Author: Florian Weimer <fweimer@redhat.com>
2701 Date: Fri Aug 9 17:01:17 2024 +0200
2703 support: Add options list terminator to the test driver
2705 This avoids crashes if a test is passed unknown options.
2707 Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2708 (cherry picked from commit c2a474f4617ede7a8bf56b7257acb37dc757b2d1)
2710 diff --git a/support/test-driver.c b/support/test-driver.c
2711 index f4c3e4d666..04ceebc08f 100644
2712 --- a/support/test-driver.c
2713 +++ b/support/test-driver.c
2714 @@ -155,6 +155,7 @@ main (int argc, char **argv)
2716 CMDLINE_OPTIONS
2717 TEST_DEFAULT_OPTIONS
2718 + { 0, }
2720 test_config.options = &options;
2721 #endif
2723 commit e3556937c2402b8acf2e586bf53168e9f482ba91
2724 Author: H.J. Lu <hjl.tools@gmail.com>
2725 Date: Mon Jul 22 17:47:21 2024 -0700
2727 x86-64: Remove sysdeps/x86_64/x32/dl-machine.h
2729 Remove sysdeps/x86_64/x32/dl-machine.h by folding x32 ARCH_LA_PLTENTER,
2730 ARCH_LA_PLTEXIT and RTLD_START into sysdeps/x86_64/dl-machine.h. There
2731 are no regressions on x86-64 nor x32. There are no changes in x86-64
2732 _dl_start_user. On x32, _dl_start_user changes are
2734 <_dl_start_user>:
2735 mov %eax,%r12d
2736 + mov %esp,%r13d
2737 mov (%rsp),%edx
2738 mov %edx,%esi
2739 - mov %esp,%r13d
2740 and $0xfffffff0,%esp
2741 mov 0x0(%rip),%edi # <_dl_start_user+0x14>
2742 lea 0x8(%r13,%rdx,4),%ecx
2744 Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2745 Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
2746 (cherry picked from commit 652c6cf26927352fc0e37e4e60c6fc98ddf6d3b4)
2748 diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
2749 index a6de3793e4..4f12955875 100644
2750 --- a/sysdeps/x86_64/dl-machine.h
2751 +++ b/sysdeps/x86_64/dl-machine.h
2752 @@ -139,37 +139,37 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
2753 .globl _start\n\
2754 .globl _dl_start_user\n\
2755 _start:\n\
2756 - movq %rsp, %rdi\n\
2757 + mov %" RSP_LP ", %" RDI_LP "\n\
2758 call _dl_start\n\
2759 _dl_start_user:\n\
2760 # Save the user entry point address in %r12.\n\
2761 - movq %rax, %r12\n\
2762 + mov %" RAX_LP ", %" R12_LP "\n\
2763 # Save %rsp value in %r13.\n\
2764 - movq %rsp, %r13\n\
2765 + mov %" RSP_LP ", % " R13_LP "\n\
2767 RTLD_START_ENABLE_X86_FEATURES \
2769 # Read the original argument count.\n\
2770 - movq (%rsp), %rdx\n\
2771 + mov (%rsp), %" RDX_LP "\n\
2772 # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\
2773 # argc -> rsi\n\
2774 - movq %rdx, %rsi\n\
2775 + mov %" RDX_LP ", %" RSI_LP "\n\
2776 # And align stack for the _dl_init call. \n\
2777 - andq $-16, %rsp\n\
2778 + and $-16, %" RSP_LP "\n\
2779 # _dl_loaded -> rdi\n\
2780 - movq _rtld_local(%rip), %rdi\n\
2781 + mov _rtld_local(%rip), %" RDI_LP "\n\
2782 # env -> rcx\n\
2783 - leaq 16(%r13,%rdx,8), %rcx\n\
2784 + lea 2*" LP_SIZE "(%r13,%rdx," LP_SIZE "), %" RCX_LP "\n\
2785 # argv -> rdx\n\
2786 - leaq 8(%r13), %rdx\n\
2787 + lea " LP_SIZE "(%r13), %" RDX_LP "\n\
2788 # Clear %rbp to mark outermost frame obviously even for constructors.\n\
2789 xorl %ebp, %ebp\n\
2790 # Call the function to run the initializers.\n\
2791 call _dl_init\n\
2792 # Pass our finalizer function to the user in %rdx, as per ELF ABI.\n\
2793 - leaq _dl_fini(%rip), %rdx\n\
2794 + lea _dl_fini(%rip), %" RDX_LP "\n\
2795 # And make sure %rsp points to argc stored on the stack.\n\
2796 - movq %r13, %rsp\n\
2797 + mov %" R13_LP ", %" RSP_LP "\n\
2798 # Jump to the user's entry point.\n\
2799 jmp *%r12\n\
2800 .previous\n\
2801 @@ -234,8 +234,13 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc,
2804 /* Names of the architecture-specific auditing callback functions. */
2805 +#ifdef __LP64__
2806 #define ARCH_LA_PLTENTER x86_64_gnu_pltenter
2807 #define ARCH_LA_PLTEXIT x86_64_gnu_pltexit
2808 +#else
2809 +#define ARCH_LA_PLTENTER x32_gnu_pltenter
2810 +#define ARCH_LA_PLTEXIT x32_gnu_pltexit
2811 +#endif
2813 #endif /* !dl_machine_h */
2815 diff --git a/sysdeps/x86_64/x32/dl-machine.h b/sysdeps/x86_64/x32/dl-machine.h
2816 deleted file mode 100644
2817 index c35cee9261..0000000000
2818 --- a/sysdeps/x86_64/x32/dl-machine.h
2819 +++ /dev/null
2820 @@ -1,76 +0,0 @@
2821 -/* Machine-dependent ELF dynamic relocation inline functions. x32 version.
2822 - Copyright (C) 2012-2024 Free Software Foundation, Inc.
2823 - This file is part of the GNU C Library.
2825 - The GNU C Library is free software; you can redistribute it and/or
2826 - modify it under the terms of the GNU Lesser General Public
2827 - License as published by the Free Software Foundation; either
2828 - version 2.1 of the License, or (at your option) any later version.
2830 - The GNU C Library is distributed in the hope that it will be useful,
2831 - but WITHOUT ANY WARRANTY; without even the implied warranty of
2832 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2833 - Lesser General Public License for more details.
2835 - You should have received a copy of the GNU Lesser General Public
2836 - License along with the GNU C Library; if not, see
2837 - <https://www.gnu.org/licenses/>. */
2839 -/* Must allow <sysdeps/x86_64/dl-machine.h> to be included more than once.
2840 - See #ifdef RESOLVE_MAP in sysdeps/x86_64/dl-machine.h. */
2841 -#include <sysdeps/x86_64/dl-machine.h>
2843 -#ifndef _X32_DL_MACHINE_H
2844 -#define _X32_DL_MACHINE_H
2846 -#undef ARCH_LA_PLTENTER
2847 -#undef ARCH_LA_PLTEXIT
2848 -#undef RTLD_START
2850 -/* Names of the architecture-specific auditing callback functions. */
2851 -#define ARCH_LA_PLTENTER x32_gnu_pltenter
2852 -#define ARCH_LA_PLTEXIT x32_gnu_pltexit
2854 -/* Initial entry point code for the dynamic linker.
2855 - The C function `_dl_start' is the real entry point;
2856 - its return value is the user program's entry point. */
2857 -#define RTLD_START asm ("\n\
2858 -.text\n\
2859 - .p2align 4\n\
2860 -.globl _start\n\
2861 -.globl _dl_start_user\n\
2862 -_start:\n\
2863 - movl %esp, %edi\n\
2864 - call _dl_start\n\
2865 -_dl_start_user:\n\
2866 - # Save the user entry point address in %r12.\n\
2867 - movl %eax, %r12d\n\
2868 - # Read the original argument count.\n\
2869 - movl (%rsp), %edx\n\
2870 - # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\
2871 - # argc -> rsi\n\
2872 - movl %edx, %esi\n\
2873 - # Save %rsp value in %r13.\n\
2874 - movl %esp, %r13d\n\
2875 - # And align stack for the _dl_init call.\n\
2876 - and $-16, %esp\n\
2877 - # _dl_loaded -> rdi\n\
2878 - movl _rtld_local(%rip), %edi\n\
2879 - # env -> rcx\n\
2880 - lea 8(%r13,%rdx,4), %ecx\n\
2881 - # argv -> rdx\n\
2882 - lea 4(%r13), %edx\n\
2883 - # Clear %rbp to mark outermost frame obviously even for constructors.\n\
2884 - xorl %ebp, %ebp\n\
2885 - # Call the function to run the initializers.\n\
2886 - call _dl_init\n\
2887 - # Pass our finalizer function to the user in %rdx, as per ELF ABI.\n\
2888 - lea _dl_fini(%rip), %edx\n\
2889 - # And make sure %rsp points to argc stored on the stack.\n\
2890 - movl %r13d, %esp\n\
2891 - # Jump to the user's entry point.\n\
2892 - jmp *%r12\n\
2893 -.previous\n\
2894 -");
2896 -#endif /* !_X32_DL_MACHINE_H */
2898 commit 898f25e0b1026be5701d05715600be646e9d0714
2899 Author: H.J. Lu <hjl.tools@gmail.com>
2900 Date: Mon Jul 22 17:47:22 2024 -0700
2902 x32/cet: Support shadow stack during startup for Linux 6.10
2904 Use RXX_LP in RTLD_START_ENABLE_X86_FEATURES. Support shadow stack during
2905 startup for Linux 6.10:
2907 commit 2883f01ec37dd8668e7222dfdb5980c86fdfe277
2908 Author: H.J. Lu <hjl.tools@gmail.com>
2909 Date: Fri Mar 15 07:04:33 2024 -0700
2911 x86/shstk: Enable shadow stacks for x32
2913 1. Add shadow stack support to x32 signal.
2914 2. Use the 64-bit map_shadow_stack syscall for x32.
2915 3. Set up shadow stack for x32.
2917 Add the map_shadow_stack system call to <fixup-asm-unistd.h> and regenerate
2918 arch-syscall.h. Tested on Intel Tiger Lake with CET enabled x32. There
2919 are no regressions with CET enabled x86-64. There are no changes in CET
2920 enabled x86-64 _dl_start_user.
2922 Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2923 Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
2924 (cherry picked from commit 8344c1f5514b1b5b1c8c6e48f4b802653bd23b71)
2926 diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h
2927 index 1fe3133406..b4f7e6c9cd 100644
2928 --- a/sysdeps/unix/sysv/linux/x86_64/dl-cet.h
2929 +++ b/sysdeps/unix/sysv/linux/x86_64/dl-cet.h
2930 @@ -92,9 +92,9 @@ dl_cet_ibt_enabled (void)
2931 # Pass GL(dl_x86_feature_1) to _dl_cet_setup_features.\n\
2932 movl %edx, %edi\n\
2933 # Align stack for the _dl_cet_setup_features call.\n\
2934 - andq $-16, %rsp\n\
2935 + and $-16, %" RSP_LP "\n\
2936 call _dl_cet_setup_features\n\
2937 # Restore %rax and %rsp from %r12 and %r13.\n\
2938 - movq %r12, %rax\n\
2939 - movq %r13, %rsp\n\
2940 + mov %" R12_LP ", %" RAX_LP "\n\
2941 + mov %" R13_LP ", %" RSP_LP "\n\
2943 diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
2944 index 3040a47d72..df3e22236d 100644
2945 --- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
2946 +++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
2947 @@ -155,6 +155,7 @@
2948 #define __NR_lsm_set_self_attr 1073742284
2949 #define __NR_lstat 1073741830
2950 #define __NR_madvise 1073741852
2951 +#define __NR_map_shadow_stack 1073742277
2952 #define __NR_mbind 1073742061
2953 #define __NR_membarrier 1073742148
2954 #define __NR_memfd_create 1073742143
2955 diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
2956 index 98124169e6..47fa8af4ce 100644
2957 --- a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
2958 +++ b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
2959 @@ -15,6 +15,10 @@
2960 License along with the GNU C Library; if not, see
2961 <http://www.gnu.org/licenses/>. */
2963 +#ifndef __NR_map_shadow_stack
2964 +# define __NR_map_shadow_stack 1073742277
2965 +#endif
2967 /* X32 uses the same 64-bit syscall interface for set_thread_area. */
2968 #ifndef __NR_set_thread_area
2969 # define __NR_set_thread_area 1073742029
2971 commit c0af0c2ba016030c778bc22c55f5f9498f96b8b9
2972 Author: Noah Goldstein <goldstein.w.n@gmail.com>
2973 Date: Tue Aug 13 23:29:14 2024 +0800
2975 x86: Fix bug in strchrnul-evex512 [BZ #32078]
2977 Issue was we were expecting not matches with CHAR before the start of
2978 the string in the page cross case.
2980 The check code in the page cross case:
2982 and $0xffffffffffffffc0,%rax
2983 vmovdqa64 (%rax),%zmm17
2984 vpcmpneqb %zmm17,%zmm16,%k1
2985 vptestmb %zmm17,%zmm17,%k0{%k1}
2986 kmovq %k0,%rax
2987 inc %rax
2988 shr %cl,%rax
2989 je L(continue)
2992 expects that all characters that neither match null nor CHAR will be
2993 1s in `rax` prior to the `inc`. Then the `inc` will overflow all of
2994 the 1s where no relevant match was found.
2996 This is incorrect in the page-cross case, as the
2997 `vmovdqa64 (%rax),%zmm17` loads from before the start of the input
2998 string.
3000 If there are matches with CHAR before the start of the string, `rax`
3001 won't properly overflow.
3003 The fix is quite simple. Just replace:
3006 inc %rax
3007 shr %cl,%rax
3009 With:
3011 sar %cl,%rax
3012 inc %rax
3015 The arithmetic shift will clear any matches prior to the start of the
3016 string while maintaining the signbit so the 1s can properly overflow
3017 to zero in the case of no matches.
3018 Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
3020 (cherry picked from commit 7da08862471dfec6fdae731c2a5f351ad485c71f)
3022 diff --git a/string/test-strchr.c b/string/test-strchr.c
3023 index c795eac6fa..72b17af687 100644
3024 --- a/string/test-strchr.c
3025 +++ b/string/test-strchr.c
3026 @@ -255,6 +255,69 @@ check1 (void)
3027 check_result (impl, s, c, exp_result);
3030 +static void
3031 +check2 (void)
3033 + CHAR *s = (CHAR *) (buf1 + getpagesize () - 4 * sizeof (CHAR));
3034 + CHAR *s_begin = (CHAR *) (buf1 + getpagesize () - 64);
3035 +#ifndef USE_FOR_STRCHRNUL
3036 + CHAR *exp_result = NULL;
3037 +#else
3038 + CHAR *exp_result = s + 1;
3039 +#endif
3040 + CHAR val = 0x12;
3041 + for (; s_begin != s; ++s_begin)
3042 + *s_begin = val;
3044 + s[0] = val + 1;
3045 + s[1] = 0;
3046 + s[2] = val + 1;
3047 + s[3] = val + 1;
3050 + FOR_EACH_IMPL (impl, 0)
3051 + check_result (impl, s, val, exp_result);
3053 + s[3] = val;
3055 + FOR_EACH_IMPL (impl, 0)
3056 + check_result (impl, s, val, exp_result);
3058 + exp_result = s;
3059 + s[0] = val;
3061 + FOR_EACH_IMPL (impl, 0)
3062 + check_result (impl, s, val, exp_result);
3065 + s[3] = val + 1;
3067 + FOR_EACH_IMPL (impl, 0)
3068 + check_result (impl, s, val, exp_result);
3071 + s[0] = val + 1;
3072 + s[1] = val + 1;
3073 + s[2] = val + 1;
3074 + s[3] = val + 1;
3075 + s[4] = val;
3076 + exp_result = s + 4;
3078 + FOR_EACH_IMPL (impl, 0)
3079 + check_result (impl, s, val, exp_result);
3081 + s[4] = 0;
3082 +#ifndef USE_FOR_STRCHRNUL
3083 + exp_result = NULL;
3084 +#else
3085 + exp_result = s + 4;
3086 +#endif
3088 + FOR_EACH_IMPL (impl, 0)
3089 + check_result (impl, s, val, exp_result);
3094 test_main (void)
3096 @@ -263,7 +326,7 @@ test_main (void)
3097 test_init ();
3099 check1 ();
3101 + check2 ();
3102 printf ("%20s", "");
3103 FOR_EACH_IMPL (impl, 0)
3104 printf ("\t%s", impl->name);
3105 diff --git a/sysdeps/x86_64/multiarch/strchr-evex-base.S b/sysdeps/x86_64/multiarch/strchr-evex-base.S
3106 index 04e2c0e79e..3a0b7c9d64 100644
3107 --- a/sysdeps/x86_64/multiarch/strchr-evex-base.S
3108 +++ b/sysdeps/x86_64/multiarch/strchr-evex-base.S
3109 @@ -124,13 +124,13 @@ L(page_cross):
3110 VPCMPNE %VMM(1), %VMM(0), %k1
3111 VPTEST %VMM(1), %VMM(1), %k0{%k1}
3112 KMOV %k0, %VRAX
3113 -# ifdef USE_AS_WCSCHR
3114 + sar %cl, %VRAX
3115 +#ifdef USE_AS_WCSCHR
3116 sub $VEC_MATCH_MASK, %VRAX
3117 -# else
3118 +#else
3119 inc %VRAX
3120 -# endif
3121 +#endif
3122 /* Ignore number of character for alignment adjustment. */
3123 - shr %cl, %VRAX
3124 jz L(align_more)
3126 bsf %VRAX, %VRAX
3128 commit 586e4cd8c67df95ebb0bfecea3d007bff618d6d9
3129 Author: Florian Weimer <fweimer@redhat.com>
3130 Date: Fri Aug 9 16:17:14 2024 +0200
3132 Define __libc_initial for the static libc
3134 Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
3135 (cherry picked from commit eb0e50e9a1cf80a2ba6f33f990a08ef37a3267fb)
3137 diff --git a/include/libc-internal.h b/include/libc-internal.h
3138 index 87ac591835..1ef43ffe67 100644
3139 --- a/include/libc-internal.h
3140 +++ b/include/libc-internal.h
3141 @@ -53,6 +53,9 @@ extern __typeof (__profile_frequency) __profile_frequency attribute_hidden;
3142 is not for an audit module, not loaded via dlmopen, and not loaded
3143 via static dlopen either). */
3144 extern _Bool __libc_initial attribute_hidden;
3145 +#else
3146 +/* The static libc is always the initial namespace. */
3147 +# define __libc_initial ((_Bool) 1)
3148 #endif
3150 #endif /* _LIBC_INTERNAL */
3152 commit 709319f9de6f976f9feceb623cb2c96769e9d78b
3153 Author: Florian Weimer <fweimer@redhat.com>
3154 Date: Mon Aug 19 15:48:03 2024 +0200
3156 string: strerror, strsignal cannot use buffer after dlmopen (bug 32026)
3158 Secondary namespaces have a different malloc. Allocating the
3159 buffer in one namespace and freeing it another results in
3160 heap corruption. Fix this by using a static string (potentially
3161 translated) in secondary namespaces. It would also be possible
3162 to use the malloc from the initial namespace to manage the
3163 buffer, but these functions would still not be safe to use in
3164 auditors etc. because a call to strerror could still free a
3165 buffer while it is used by the application. Another approach
3166 could use proper initial-exec TLS, duplicated in secondary
3167 namespaces, but that would need a callback interface for freeing
3168 libc resources in namespaces on thread exit, which does not exist
3169 today.
3171 Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
3172 (cherry picked from commit 25a5eb4010df94b412c67db9e346029de316d06b)
3174 diff --git a/NEWS b/NEWS
3175 index b9eb4a558b..10a125bc66 100644
3176 --- a/NEWS
3177 +++ b/NEWS
3178 @@ -13,6 +13,7 @@ The following bugs are resolved with this release:
3179 [31968] mremap implementation in C does not handle arguments correctly
3180 [31890] resolv: Allow short error responses to match any DNS query
3181 [31968] mremap implementation in C does not handle arguments correctly
3182 + [32026] strerror/strsignal TLS not handled correctly for secondary namespaces
3183 [32052] Name space violation in fortify wrappers
3185 Version 2.40
3186 diff --git a/string/strerror_l.c b/string/strerror_l.c
3187 index 15cce261e6..70456e5bb4 100644
3188 --- a/string/strerror_l.c
3189 +++ b/string/strerror_l.c
3190 @@ -20,7 +20,7 @@
3191 #include <stdio.h>
3192 #include <string.h>
3193 #include <tls-internal.h>
3195 +#include <libc-internal.h>
3197 static const char *
3198 translate (const char *str, locale_t loc)
3199 @@ -31,6 +31,12 @@ translate (const char *str, locale_t loc)
3200 return res;
3203 +static char *
3204 +unknown_error (locale_t loc)
3206 + return (char *) translate ("Unknown error", loc);
3210 /* Return a string describing the errno code in ERRNUM. */
3211 char *
3212 @@ -40,18 +46,25 @@ __strerror_l (int errnum, locale_t loc)
3213 char *err = (char *) __get_errlist (errnum);
3214 if (__glibc_unlikely (err == NULL))
3216 - struct tls_internal_t *tls_internal = __glibc_tls_internal ();
3217 - free (tls_internal->strerror_l_buf);
3218 - if (__asprintf (&tls_internal->strerror_l_buf, "%s%d",
3219 - translate ("Unknown error ", loc), errnum) > 0)
3220 - err = tls_internal->strerror_l_buf;
3221 - else
3222 + if (__libc_initial)
3224 - /* The memory was freed above. */
3225 - tls_internal->strerror_l_buf = NULL;
3226 - /* Provide a fallback translation. */
3227 - err = (char *) translate ("Unknown error", loc);
3228 + struct tls_internal_t *tls_internal = __glibc_tls_internal ();
3229 + free (tls_internal->strerror_l_buf);
3230 + if (__asprintf (&tls_internal->strerror_l_buf, "%s%d",
3231 + translate ("Unknown error ", loc), errnum) > 0)
3232 + err = tls_internal->strerror_l_buf;
3233 + else
3235 + /* The memory was freed above. */
3236 + tls_internal->strerror_l_buf = NULL;
3237 + /* Provide a fallback translation. */
3238 + err = unknown_error (loc);
3241 + else
3242 + /* Secondary namespaces use a different malloc, so cannot
3243 + participate in the buffer management. */
3244 + err = unknown_error (loc);
3246 else
3247 err = (char *) translate (err, loc);
3248 diff --git a/string/strsignal.c b/string/strsignal.c
3249 index 3114601564..d9b0365468 100644
3250 --- a/string/strsignal.c
3251 +++ b/string/strsignal.c
3252 @@ -21,6 +21,7 @@
3253 #include <string.h>
3254 #include <libintl.h>
3255 #include <tls-internal.h>
3256 +#include <libc-internal.h>
3258 /* Return a string describing the meaning of the signal number SIGNUM. */
3259 char *
3260 @@ -30,21 +31,28 @@ strsignal (int signum)
3261 if (desc != NULL)
3262 return _(desc);
3264 - struct tls_internal_t *tls_internal = __glibc_tls_internal ();
3265 - free (tls_internal->strsignal_buf);
3266 + if (__libc_initial)
3268 + struct tls_internal_t *tls_internal = __glibc_tls_internal ();
3269 + free (tls_internal->strsignal_buf);
3271 - int r;
3272 + int r;
3273 #ifdef SIGRTMIN
3274 - if (signum >= SIGRTMIN && signum <= SIGRTMAX)
3275 - r = __asprintf (&tls_internal->strsignal_buf, _("Real-time signal %d"),
3276 - signum - SIGRTMIN);
3277 - else
3278 + if (signum >= SIGRTMIN && signum <= SIGRTMAX)
3279 + r = __asprintf (&tls_internal->strsignal_buf, _("Real-time signal %d"),
3280 + signum - SIGRTMIN);
3281 + else
3282 #endif
3283 - r = __asprintf (&tls_internal->strsignal_buf, _("Unknown signal %d"),
3284 - signum);
3286 - if (r == -1)
3287 - tls_internal->strsignal_buf = NULL;
3289 - return tls_internal->strsignal_buf;
3290 + r = __asprintf (&tls_internal->strsignal_buf, _("Unknown signal %d"),
3291 + signum);
3293 + if (r >= 0)
3294 + return tls_internal->strsignal_buf;
3295 + else
3296 + tls_internal->strsignal_buf = NULL;
3298 + /* Fall through on asprintf error, and for !__libc_initial:
3299 + secondary namespaces use a different malloc and cannot
3300 + participate in the buffer management. */
3301 + return _("Unknown signal");
3304 commit bc240ba7c86a74bc64d4234feadb49bb8e36e1c9
3305 Author: Maciej W. Rozycki <macro@redhat.com>
3306 Date: Fri Jul 26 13:21:34 2024 +0100
3308 support: Add FAIL test failure helper
3310 Add a FAIL test failure helper analogous to FAIL_RET, that does not
3311 cause the current function to return, providing a standardized way to
3312 report a test failure with a message supplied while permitting the
3313 caller to continue executing, for further reporting, cleaning up, etc.
3315 Update existing test cases that provide a conflicting definition of FAIL
3316 by removing the local FAIL definition and then as follows:
3318 - tst-fortify-syslog: provide a meaningful message in addition to the
3319 file name already added by <support/check.h>; 'support_record_failure'
3320 is already called by 'support_print_failure_impl' invoked by the new
3321 FAIL test failure helper.
3323 - tst-ctype: no update to FAIL calls required, with the name of the file
3324 and the line number within of the failure site additionally included
3325 by the new FAIL test failure helper, and error counting plus count
3326 reporting upon test program termination also already provided by
3327 'support_record_failure' and 'support_report_failure' respectively,
3328 called by 'support_print_failure_impl' and 'adjust_exit_status' also
3329 respectively. However in a number of places 'printf' is called and
3330 the error count adjusted by hand, so update these places to make use
3331 of FAIL instead. And last but not least adjust the final summary just
3332 to report completion, with any error count following as reported by
3333 the test driver.
3335 - test-tgmath2: no update to FAIL calls required, with the name of the
3336 file of the failure site additionally included by the new FAIL test
3337 failure helper. Also there is no need to track the return status by
3338 hand as any call to FAIL will eventually cause the test case to return
3339 an unsuccesful exit status regardless of the return status from the
3340 test function, via a call to 'adjust_exit_status' made by the test
3341 driver.
3343 Reviewed-by: DJ Delorie <dj@redhat.com>
3344 (cherry picked from commit 1b97a9f23bf605ca608162089c94187573fb2a9e)
3346 diff --git a/debug/tst-fortify-syslog.c b/debug/tst-fortify-syslog.c
3347 index a7ddbf7c6b..2712acf689 100644
3348 --- a/debug/tst-fortify-syslog.c
3349 +++ b/debug/tst-fortify-syslog.c
3350 @@ -22,7 +22,6 @@
3351 #include <syslog.h>
3352 #include <string.h>
3353 #include <unistd.h>
3354 -#include <stdio.h>
3356 #include <support/check.h>
3357 #include <support/support.h>
3358 @@ -46,18 +45,13 @@ handler (int sig)
3359 _exit (127);
3362 -#define FAIL() \
3363 - do { \
3364 - printf ("Failure on line %d\n", __LINE__); \
3365 - support_record_failure (); \
3366 - } while (0)
3367 #define CHK_FAIL_START \
3368 chk_fail_ok = 1; \
3369 if (! setjmp (chk_fail_buf)) \
3371 #define CHK_FAIL_END \
3372 chk_fail_ok = 0; \
3373 - FAIL (); \
3374 + FAIL ("not supposed to reach here"); \
3377 static void
3378 diff --git a/localedata/tst-ctype.c b/localedata/tst-ctype.c
3379 index 9de979a2d7..a23689719c 100644
3380 --- a/localedata/tst-ctype.c
3381 +++ b/localedata/tst-ctype.c
3382 @@ -21,6 +21,8 @@
3383 #include <stdio.h>
3384 #include <string.h>
3386 +#include <support/check.h>
3389 static const char lower[] = "abcdefghijklmnopqrstuvwxyz";
3390 static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
3391 @@ -53,19 +55,11 @@ static struct classes
3392 #define nclasses (sizeof (classes) / sizeof (classes[0]))
3395 -#define FAIL(str, args...) \
3396 - { \
3397 - printf (" " str "\n", ##args); \
3398 - ++errors; \
3402 static int
3403 do_test (void)
3405 const char *cp;
3406 const char *cp2;
3407 - int errors = 0;
3408 char *inpline = NULL;
3409 size_t inplinelen = 0;
3410 char *resline = NULL;
3411 @@ -394,11 +388,8 @@ punct = %04x alnum = %04x\n",
3413 if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0)
3414 != (*resp != '0'))
3416 - printf (" is%s('%c' = '\\x%02x') %s true\n", inpline,
3417 - *inp, *inp, *resp == '1' ? "not" : "is");
3418 - ++errors;
3420 + FAIL (" is%s('%c' = '\\x%02x') %s true\n", inpline,
3421 + *inp, *inp, *resp == '1' ? "not" : "is");
3422 ++inp;
3423 ++resp;
3425 @@ -408,11 +399,8 @@ punct = %04x alnum = %04x\n",
3426 while (*inp != '\0')
3428 if (tolower (*inp) != *resp)
3430 - printf (" tolower('%c' = '\\x%02x') != '%c'\n",
3431 - *inp, *inp, *resp);
3432 - ++errors;
3434 + FAIL (" tolower('%c' = '\\x%02x') != '%c'\n",
3435 + *inp, *inp, *resp);
3436 ++inp;
3437 ++resp;
3439 @@ -422,11 +410,8 @@ punct = %04x alnum = %04x\n",
3440 while (*inp != '\0')
3442 if (toupper (*inp) != *resp)
3444 - printf (" toupper('%c' = '\\x%02x') != '%c'\n",
3445 - *inp, *inp, *resp);
3446 - ++errors;
3448 + FAIL (" toupper('%c' = '\\x%02x') != '%c'\n",
3449 + *inp, *inp, *resp);
3450 ++inp;
3451 ++resp;
3453 @@ -436,14 +421,7 @@ punct = %04x alnum = %04x\n",
3457 - if (errors != 0)
3459 - printf (" %d error%s for `%s' locale\n\n\n", errors,
3460 - errors == 1 ? "" : "s", setlocale (LC_ALL, NULL));
3461 - return 1;
3464 - printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
3465 + printf ("Completed testing for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
3466 return 0;
3469 diff --git a/math/test-tgmath2.c b/math/test-tgmath2.c
3470 index 37afa8a08a..4aeb877b8e 100644
3471 --- a/math/test-tgmath2.c
3472 +++ b/math/test-tgmath2.c
3473 @@ -24,6 +24,8 @@
3474 #include <string.h>
3475 #include <tgmath.h>
3477 +#include <support/check.h>
3479 //#define DEBUG
3481 typedef complex float cfloat;
3482 @@ -87,13 +89,6 @@ enum
3483 int count;
3484 int counts[Tlast][C_last];
3486 -#define FAIL(str) \
3487 - do \
3488 - { \
3489 - printf ("%s failure on line %d\n", (str), __LINE__); \
3490 - result = 1; \
3491 - } \
3492 - while (0)
3493 #define TEST_TYPE_ONLY(expr, rettype) \
3494 do \
3496 @@ -133,8 +128,6 @@ int counts[Tlast][C_last];
3498 test_cos (const int Vint4, const long long int Vllong4)
3500 - int result = 0;
3502 TEST (cos (vfloat1), float, cos);
3503 TEST (cos (vdouble1), double, cos);
3504 TEST (cos (vldouble1), ldouble, cos);
3505 @@ -152,7 +145,7 @@ test_cos (const int Vint4, const long long int Vllong4)
3506 TEST (cos (Vcdouble1), cdouble, cos);
3507 TEST (cos (Vcldouble1), cldouble, cos);
3509 - return result;
3510 + return 0;
3514 diff --git a/support/check.h b/support/check.h
3515 index 711f34b83b..7ea22c7a2c 100644
3516 --- a/support/check.h
3517 +++ b/support/check.h
3518 @@ -24,6 +24,11 @@
3520 __BEGIN_DECLS
3522 +/* Record a test failure, print the failure message to standard output
3523 + and pass the result of 1 through. */
3524 +#define FAIL(...) \
3525 + support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__)
3527 /* Record a test failure, print the failure message to standard output
3528 and return 1. */
3529 #define FAIL_RET(...) \
3531 commit 27fb563bfee521239316142fa4968282bffa86a6
3532 Author: Maciej W. Rozycki <macro@redhat.com>
3533 Date: Fri Jul 26 13:21:34 2024 +0100
3535 stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650]
3537 Complement commit b03e4d7bd25b ("stdio: fix vfscanf with matches longer
3538 than INT_MAX (bug 27650)") and add a test case for the issue, inspired
3539 by the reproducer provided with the bug report.
3541 This has been verified to succeed as from the commit referred and fail
3542 beforehand.
3544 As the test requires 2GiB of data to be passed around its performance
3545 has been evaluated using a choice of systems and the execution time
3546 determined to be respectively in the range of 9s for POWER9@2.166GHz,
3547 24s for FU740@1.2GHz, and 40s for 74Kf@950MHz. As this is on the verge
3548 of and beyond the default timeout it has been increased by the factor of
3549 8. Regardless, following recent practice the test has been added to the
3550 standard rather than extended set.
3552 Reviewed-by: DJ Delorie <dj@redhat.com>
3553 (cherry picked from commit 89cddc8a7096f3d9225868304d2bc0a1aaf07d63)
3555 diff --git a/stdio-common/Makefile b/stdio-common/Makefile
3556 index a63c05a120..e4f0146d2c 100644
3557 --- a/stdio-common/Makefile
3558 +++ b/stdio-common/Makefile
3559 @@ -240,6 +240,7 @@ tests := \
3560 tst-scanf-binary-c23 \
3561 tst-scanf-binary-gnu11 \
3562 tst-scanf-binary-gnu89 \
3563 + tst-scanf-bz27650 \
3564 tst-scanf-intn \
3565 tst-scanf-round \
3566 tst-scanf-to_inpunct \
3567 @@ -328,6 +329,7 @@ generated += \
3568 tst-printf-fp-free.mtrace \
3569 tst-printf-fp-leak-mem.out \
3570 tst-printf-fp-leak.mtrace \
3571 + tst-scanf-bz27650.mtrace \
3572 tst-vfprintf-width-prec-mem.out \
3573 tst-vfprintf-width-prec.mtrace \
3574 # generated
3575 @@ -419,6 +421,9 @@ tst-printf-fp-free-ENV = \
3576 tst-printf-fp-leak-ENV = \
3577 MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace \
3578 LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
3579 +tst-scanf-bz27650-ENV = \
3580 + MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \
3581 + LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
3583 $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
3584 $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
3585 diff --git a/stdio-common/tst-scanf-bz27650.c b/stdio-common/tst-scanf-bz27650.c
3586 new file mode 100644
3587 index 0000000000..3a742bc865
3588 --- /dev/null
3589 +++ b/stdio-common/tst-scanf-bz27650.c
3590 @@ -0,0 +1,108 @@
3591 +/* Test for BZ #27650, formatted input matching beyond INT_MAX.
3592 + Copyright (C) 2024 Free Software Foundation, Inc.
3593 + This file is part of the GNU C Library.
3595 + The GNU C Library is free software; you can redistribute it and/or
3596 + modify it under the terms of the GNU Lesser General Public
3597 + License as published by the Free Software Foundation; either
3598 + version 2.1 of the License, or (at your option) any later version.
3600 + The GNU C Library is distributed in the hope that it will be useful,
3601 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3602 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3603 + Lesser General Public License for more details.
3605 + You should have received a copy of the GNU Lesser General Public
3606 + License along with the GNU C Library; if not, see
3607 + <https://www.gnu.org/licenses/>. */
3609 +#include <error.h>
3610 +#include <errno.h>
3611 +#include <limits.h>
3612 +#include <mcheck.h>
3613 +#include <stddef.h>
3614 +#include <stdio.h>
3615 +#include <stdlib.h>
3616 +#include <string.h>
3618 +#include <sys/types.h>
3620 +#include <support/check.h>
3621 +#include <support/test-driver.h>
3623 +/* Produce a stream of more than INT_MAX characters via buffer BUF of
3624 + size SIZE according to bookkeeping in COOKIE and then return EOF. */
3626 +static ssize_t
3627 +io_read (void *cookie, char *buf, size_t size)
3629 + unsigned int *written = cookie;
3630 + unsigned int w = *written;
3632 + if (w > INT_MAX)
3633 + return 0;
3635 + memset (buf, 'a', size);
3636 + *written = w + size;
3637 + return size;
3640 +/* Consume a stream of more than INT_MAX characters from an artificial
3641 + input stream of which none is the new line character. The call to
3642 + fscanf is supposed to complete upon the EOF condition of input,
3643 + however in the presence of BZ #27650 it will terminate prematurely
3644 + with characters still outstanding in input. Diagnose the condition
3645 + and return status accordingly. */
3647 +int
3648 +do_test (void)
3650 + static cookie_io_functions_t io_funcs = { .read = io_read };
3651 + unsigned int written = 0;
3652 + FILE *in;
3653 + int v;
3655 + mtrace ();
3657 + in = fopencookie (&written, "r", io_funcs);
3658 + if (in == NULL)
3660 + FAIL ("fopencookie: %m");
3661 + goto out;
3664 + v = fscanf (in, "%*[^\n]");
3665 + if (ferror (in))
3667 + FAIL ("fscanf: input failure, at %u: %m", written);
3668 + goto out_close;
3670 + else if (v == EOF)
3672 + FAIL ("fscanf: unexpected end of file, at %u", written);
3673 + goto out_close;
3676 + if (!feof (in))
3678 + v = fgetc (in);
3679 + if (ferror (in))
3680 + FAIL ("fgetc: input failure: %m");
3681 + else if (v == EOF)
3682 + FAIL ("fgetc: unexpected end of file after missing end of file");
3683 + else if (v == '\n')
3684 + FAIL ("unexpected new line character received");
3685 + else
3686 + FAIL ("character received after end of file expected: \\x%02x", v);
3689 +out_close:
3690 + if (fclose (in) != 0)
3691 + FAIL ("fclose: %m");
3693 +out:
3694 + return EXIT_SUCCESS;
3697 +#define TIMEOUT (DEFAULT_TIMEOUT * 8)
3698 +#include <support/test-driver.c>
3700 commit 2f749d2b15cbc82268d7f8735f21ae1e3b68754f
3701 Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
3702 Date: Wed Aug 14 19:20:04 2024 -0400
3704 Make tst-ungetc use libsupport
3706 Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
3707 Reviewed-by: Carlos O'Donell <carlos@redhat.com>
3708 (cherry picked from commit 3f7df7e757f4efec38e45d4068e5492efcac4856)
3710 diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
3711 index 1344b2b591..5c808f0734 100644
3712 --- a/stdio-common/tst-ungetc.c
3713 +++ b/stdio-common/tst-ungetc.c
3714 @@ -1,70 +1,72 @@
3715 -/* Test for ungetc bugs. */
3716 +/* Test for ungetc bugs.
3717 + Copyright (C) 1996-2024 Free Software Foundation, Inc.
3718 + Copyright The GNU Toolchain Authors.
3719 + This file is part of the GNU C Library.
3721 + The GNU C Library is free software; you can redistribute it and/or
3722 + modify it under the terms of the GNU Lesser General Public
3723 + License as published by the Free Software Foundation; either
3724 + version 2.1 of the License, or (at your option) any later version.
3726 + The GNU C Library is distributed in the hope that it will be useful,
3727 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3728 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3729 + Lesser General Public License for more details.
3731 + You should have received a copy of the GNU Lesser General Public
3732 + License along with the GNU C Library; if not, see
3733 + <https://www.gnu.org/licenses/>. */
3735 #include <stdio.h>
3736 #include <stdlib.h>
3737 -#include <unistd.h>
3739 -#undef assert
3740 -#define assert(x) \
3741 - if (!(x)) \
3742 - { \
3743 - fputs ("test failed: " #x "\n", stderr); \
3744 - retval = 1; \
3745 - goto the_end; \
3747 +#include <support/check.h>
3748 +#include <support/support.h>
3749 +#include <support/temp_file.h>
3750 +#include <support/xstdio.h>
3751 +#include <support/xunistd.h>
3753 -int
3754 -main (int argc, char *argv[])
3755 +static int
3756 +do_test (void)
3758 - char name[] = "/tmp/tst-ungetc.XXXXXX";
3759 + char *name = NULL;
3760 FILE *fp = NULL;
3761 - int retval = 0;
3762 int c;
3763 char buffer[64];
3765 - int fd = mkstemp (name);
3766 + int fd = create_temp_file ("tst-ungetc.", &name);
3767 if (fd == -1)
3769 - printf ("mkstemp failed: %m\n");
3770 - return 1;
3772 - close (fd);
3773 - fp = fopen (name, "w");
3774 - assert (fp != NULL)
3775 - fputs ("bla", fp);
3776 - fclose (fp);
3777 - fp = NULL;
3778 + FAIL_EXIT1 ("cannot create temporary file: %m");
3779 + xclose (fd);
3781 - fp = fopen (name, "r");
3782 - assert (fp != NULL);
3783 - assert (ungetc ('z', fp) == 'z');
3784 - assert (getc (fp) == 'z');
3785 - assert (getc (fp) == 'b');
3786 - assert (getc (fp) == 'l');
3787 - assert (ungetc ('m', fp) == 'm');
3788 - assert (getc (fp) == 'm');
3789 - assert ((c = getc (fp)) == 'a');
3790 - assert (getc (fp) == EOF);
3791 - assert (ungetc (c, fp) == c);
3792 - assert (feof (fp) == 0);
3793 - assert (getc (fp) == c);
3794 - assert (getc (fp) == EOF);
3795 - fclose (fp);
3796 - fp = NULL;
3797 + fp = xfopen (name, "w");
3798 + fputs ("bla", fp);
3799 + xfclose (fp);
3801 - fp = fopen (name, "r");
3802 - assert (fp != NULL);
3803 - assert (getc (fp) == 'b');
3804 - assert (getc (fp) == 'l');
3805 - assert (ungetc ('b', fp) == 'b');
3806 - assert (fread (buffer, 1, 64, fp) == 2);
3807 - assert (buffer[0] == 'b');
3808 - assert (buffer[1] == 'a');
3809 + fp = xfopen (name, "r");
3810 + TEST_VERIFY_EXIT (ungetc ('z', fp) == 'z');
3811 + TEST_VERIFY_EXIT (getc (fp) == 'z');
3812 + TEST_VERIFY_EXIT (getc (fp) == 'b');
3813 + TEST_VERIFY_EXIT (getc (fp) == 'l');
3814 + TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
3815 + TEST_VERIFY_EXIT (getc (fp) == 'm');
3816 + TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
3817 + TEST_VERIFY_EXIT (getc (fp) == EOF);
3818 + TEST_VERIFY_EXIT (ungetc (c, fp) == c);
3819 + TEST_VERIFY_EXIT (feof (fp) == 0);
3820 + TEST_VERIFY_EXIT (getc (fp) == c);
3821 + TEST_VERIFY_EXIT (getc (fp) == EOF);
3822 + xfclose (fp);
3824 -the_end:
3825 - if (fp != NULL)
3826 - fclose (fp);
3827 - unlink (name);
3828 + fp = xfopen (name, "r");
3829 + TEST_VERIFY_EXIT (getc (fp) == 'b');
3830 + TEST_VERIFY_EXIT (getc (fp) == 'l');
3831 + TEST_VERIFY_EXIT (ungetc ('b', fp) == 'b');
3832 + TEST_VERIFY_EXIT (fread (buffer, 1, 64, fp) == 2);
3833 + TEST_VERIFY_EXIT (buffer[0] == 'b');
3834 + TEST_VERIFY_EXIT (buffer[1] == 'a');
3835 + xfclose (fp);
3837 - return retval;
3838 + return 0;
3841 +#include <support/test-driver.c>
3843 commit dac7a0694b5e853f08be518cd5a133ac5804666d
3844 Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
3845 Date: Tue Aug 13 21:00:06 2024 -0400
3847 ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]
3849 When ungetc is called on an unused stream, the backup buffer is
3850 allocated without the main get area being present. This results in
3851 every subsequent ungetc (as the stream remains in the backup area)
3852 checking uninitialized memory in the backup buffer when trying to put a
3853 character back into the stream.
3855 Avoid comparing the input character with buffer contents when in backup
3856 to avoid this uninitialized read. The uninitialized read is harmless in
3857 this context since the location is promptly overwritten with the input
3858 character, thus fulfilling ungetc functionality.
3860 Also adjust wording in the manual to drop the paragraph that says glibc
3861 cannot do multiple ungetc back to back since with this change, ungetc
3862 can actually do this.
3864 Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
3865 Reviewed-by: Carlos O'Donell <carlos@redhat.com>
3866 (cherry picked from commit cdf0f88f97b0aaceb894cc02b21159d148d7065c)
3868 diff --git a/libio/genops.c b/libio/genops.c
3869 index 99f5e80f20..b012fa33d2 100644
3870 --- a/libio/genops.c
3871 +++ b/libio/genops.c
3872 @@ -662,7 +662,7 @@ _IO_sputbackc (FILE *fp, int c)
3874 int result;
3876 - if (fp->_IO_read_ptr > fp->_IO_read_base
3877 + if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
3878 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
3880 fp->_IO_read_ptr--;
3881 diff --git a/manual/stdio.texi b/manual/stdio.texi
3882 index 8517653507..92614775fa 100644
3883 --- a/manual/stdio.texi
3884 +++ b/manual/stdio.texi
3885 @@ -1467,11 +1467,9 @@ program; usually @code{ungetc} is used only to unread a character that
3886 was just read from the same stream. @Theglibc{} supports this
3887 even on files opened in binary mode, but other systems might not.
3889 -@Theglibc{} only supports one character of pushback---in other
3890 -words, it does not work to call @code{ungetc} twice without doing input
3891 -in between. Other systems might let you push back multiple characters;
3892 -then reading from the stream retrieves the characters in the reverse
3893 -order that they were pushed.
3894 +@Theglibc{} supports pushing back multiple characters; subsequently
3895 +reading from the stream retrieves the characters in the reverse order
3896 +that they were pushed.
3898 Pushing back characters doesn't alter the file; only the internal
3899 buffering for the stream is affected. If a file positioning function
3900 diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
3901 index 5c808f0734..388b202493 100644
3902 --- a/stdio-common/tst-ungetc.c
3903 +++ b/stdio-common/tst-ungetc.c
3904 @@ -48,6 +48,8 @@ do_test (void)
3905 TEST_VERIFY_EXIT (getc (fp) == 'b');
3906 TEST_VERIFY_EXIT (getc (fp) == 'l');
3907 TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
3908 + TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n');
3909 + TEST_VERIFY_EXIT (getc (fp) == 'n');
3910 TEST_VERIFY_EXIT (getc (fp) == 'm');
3911 TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
3912 TEST_VERIFY_EXIT (getc (fp) == EOF);
3914 commit e24902f409994f226dbc6fde2476009df452a18f
3915 Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
3916 Date: Tue Aug 13 21:08:49 2024 -0400
3918 ungetc: Fix backup buffer leak on program exit [BZ #27821]
3920 If a file descriptor is left unclosed and is cleaned up by _IO_cleanup
3921 on exit, its backup buffer remains unfreed, registering as a leak in
3922 valgrind. This is not strictly an issue since (1) the program should
3923 ideally be closing the stream once it's not in use and (2) the program
3924 is about to exit anyway, so keeping the backup buffer around a wee bit
3925 longer isn't a real problem. Free it anyway to keep valgrind happy
3926 when the streams in question are the standard ones, i.e. stdout, stdin
3927 or stderr.
3929 Also, the _IO_have_backup macro checks for _IO_save_base,
3930 which is a roundabout way to check for a backup buffer instead of
3931 directly looking for _IO_backup_base. The roundabout check breaks when
3932 the main get area has not been used and user pushes a char into the
3933 backup buffer with ungetc. Fix this to use the _IO_backup_base
3934 directly.
3936 Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
3937 Reviewed-by: Carlos O'Donell <carlos@redhat.com>
3938 (cherry picked from commit 3e1d8d1d1dca24ae90df2ea826a8916896fc7e77)
3940 diff --git a/libio/genops.c b/libio/genops.c
3941 index b012fa33d2..35d8b30710 100644
3942 --- a/libio/genops.c
3943 +++ b/libio/genops.c
3944 @@ -816,6 +816,12 @@ _IO_unbuffer_all (void)
3945 legacy = 1;
3946 #endif
3948 + /* Free up the backup area if it was ever allocated. */
3949 + if (_IO_have_backup (fp))
3950 + _IO_free_backup_area (fp);
3951 + if (fp->_mode > 0 && _IO_have_wbackup (fp))
3952 + _IO_free_wbackup_area (fp);
3954 if (! (fp->_flags & _IO_UNBUFFERED)
3955 /* Iff stream is un-orientated, it wasn't used. */
3956 && (legacy || fp->_mode != 0))
3957 diff --git a/libio/libioP.h b/libio/libioP.h
3958 index 1af287b19f..616253fcd0 100644
3959 --- a/libio/libioP.h
3960 +++ b/libio/libioP.h
3961 @@ -577,8 +577,8 @@ extern void _IO_old_init (FILE *fp, int flags) __THROW;
3962 ((__fp)->_wide_data->_IO_write_base \
3963 = (__fp)->_wide_data->_IO_write_ptr = __p, \
3964 (__fp)->_wide_data->_IO_write_end = (__ep))
3965 -#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL)
3966 -#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL)
3967 +#define _IO_have_backup(fp) ((fp)->_IO_backup_base != NULL)
3968 +#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_backup_base != NULL)
3969 #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP)
3970 #define _IO_have_markers(fp) ((fp)->_markers != NULL)
3971 #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
3972 diff --git a/stdio-common/Makefile b/stdio-common/Makefile
3973 index e4f0146d2c..a91754f52d 100644
3974 --- a/stdio-common/Makefile
3975 +++ b/stdio-common/Makefile
3976 @@ -254,6 +254,7 @@ tests := \
3977 tst-swscanf \
3978 tst-tmpnam \
3979 tst-ungetc \
3980 + tst-ungetc-leak \
3981 tst-unlockedio \
3982 tst-vfprintf-mbs-prec \
3983 tst-vfprintf-user-type \
3984 @@ -316,6 +317,7 @@ tests-special += \
3985 $(objpfx)tst-printf-bz25691-mem.out \
3986 $(objpfx)tst-printf-fp-free-mem.out \
3987 $(objpfx)tst-printf-fp-leak-mem.out \
3988 + $(objpfx)tst-ungetc-leak-mem.out \
3989 $(objpfx)tst-vfprintf-width-prec-mem.out \
3990 # tests-special
3992 @@ -330,6 +332,8 @@ generated += \
3993 tst-printf-fp-leak-mem.out \
3994 tst-printf-fp-leak.mtrace \
3995 tst-scanf-bz27650.mtrace \
3996 + tst-ungetc-leak-mem.out \
3997 + tst-ungetc-leak.mtrace \
3998 tst-vfprintf-width-prec-mem.out \
3999 tst-vfprintf-width-prec.mtrace \
4000 # generated
4001 @@ -424,6 +428,9 @@ tst-printf-fp-leak-ENV = \
4002 tst-scanf-bz27650-ENV = \
4003 MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \
4004 LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
4005 +tst-ungetc-leak-ENV = \
4006 + MALLOC_TRACE=$(objpfx)tst-ungetc-leak.mtrace \
4007 + LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so
4009 $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
4010 $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
4011 diff --git a/stdio-common/tst-ungetc-leak.c b/stdio-common/tst-ungetc-leak.c
4012 new file mode 100644
4013 index 0000000000..6c5152b43f
4014 --- /dev/null
4015 +++ b/stdio-common/tst-ungetc-leak.c
4016 @@ -0,0 +1,32 @@
4017 +/* Test for memory leak with ungetc when stream is unused.
4018 + Copyright The GNU Toolchain Authors.
4019 + This file is part of the GNU C Library.
4021 + The GNU C Library is free software; you can redistribute it and/or
4022 + modify it under the terms of the GNU Lesser General Public
4023 + License as published by the Free Software Foundation; either
4024 + version 2.1 of the License, or (at your option) any later version.
4026 + The GNU C Library is distributed in the hope that it will be useful,
4027 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4028 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4029 + Lesser General Public License for more details.
4031 + You should have received a copy of the GNU Lesser General Public
4032 + License along with the GNU C Library; if not, see
4033 + <https://www.gnu.org/licenses/>. */
4035 +#include <stdio.h>
4036 +#include <mcheck.h>
4037 +#include <support/check.h>
4038 +#include <support/support.h>
4040 +static int
4041 +do_test (void)
4043 + mtrace ();
4044 + TEST_COMPARE (ungetc('y', stdin), 'y');
4045 + return 0;
4048 +#include <support/test-driver.c>
4050 commit 3b3350d7baa8de70b71c02e964d5b8343749ebf8
4051 Author: Maciej W. Rozycki <macro@redhat.com>
4052 Date: Fri Jul 26 13:21:34 2024 +0100
4054 posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64
4056 Remove local FAIL macro in favor to FAIL_RET from <support/check.h>,
4057 which provides equivalent reporting, with the name of the file of the
4058 failure site additionally included, for the tst-truncate-common core
4059 shared between the tst-truncate and tst-truncate64 tests.
4061 Reviewed-by: DJ Delorie <dj@redhat.com>
4062 (cherry picked from commit fe47595504a55e7bb992f8928533df154b510383)
4064 diff --git a/posix/tst-truncate-common.c b/posix/tst-truncate-common.c
4065 index b774fa46b8..b8c561ffdb 100644
4066 --- a/posix/tst-truncate-common.c
4067 +++ b/posix/tst-truncate-common.c
4068 @@ -21,6 +21,8 @@
4069 #include <sys/stat.h>
4070 #include <unistd.h>
4072 +#include <support/check.h>
4074 static void do_prepare (void);
4075 #define PREPARE(argc, argv) do_prepare ()
4076 static int do_test (void);
4077 @@ -42,9 +44,6 @@ do_prepare (void)
4081 -#define FAIL(str) \
4082 - do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0)
4084 static int
4085 do_test_with_offset (off_t offset)
4087 @@ -54,35 +53,35 @@ do_test_with_offset (off_t offset)
4088 memset (buf, 0xcf, sizeof (buf));
4090 if (pwrite (temp_fd, buf, sizeof (buf), offset) != sizeof (buf))
4091 - FAIL ("write failed");
4092 + FAIL_RET ("write failed");
4093 if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + sizeof (buf)))
4094 - FAIL ("initial size wrong");
4095 + FAIL_RET ("initial size wrong");
4097 if (ftruncate (temp_fd, offset + 800) < 0)
4098 - FAIL ("size reduction with ftruncate failed");
4099 + FAIL_RET ("size reduction with ftruncate failed");
4100 if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800))
4101 - FAIL ("size after reduction with ftruncate is incorrect");
4102 + FAIL_RET ("size after reduction with ftruncate is incorrect");
4104 /* The following test covers more than POSIX. POSIX does not require
4105 that ftruncate() can increase the file size. But we are testing
4106 Unix systems. */
4107 if (ftruncate (temp_fd, offset + 1200) < 0)
4108 - FAIL ("size increate with ftruncate failed");
4109 + FAIL_RET ("size increate with ftruncate failed");
4110 if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200))
4111 - FAIL ("size after increase is incorrect");
4112 + FAIL_RET ("size after increase is incorrect");
4114 if (truncate (temp_filename, offset + 800) < 0)
4115 - FAIL ("size reduction with truncate failed");
4116 + FAIL_RET ("size reduction with truncate failed");
4117 if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800))
4118 - FAIL ("size after reduction with truncate incorrect");
4119 + FAIL_RET ("size after reduction with truncate incorrect");
4121 /* The following test covers more than POSIX. POSIX does not require
4122 that truncate() can increase the file size. But we are testing
4123 Unix systems. */
4124 if (truncate (temp_filename, (offset + 1200)) < 0)
4125 - FAIL ("size increase with truncate failed");
4126 + FAIL_RET ("size increase with truncate failed");
4127 if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200))
4128 - FAIL ("size increase with truncate is incorrect");
4129 + FAIL_RET ("size increase with truncate is incorrect");
4131 return 0;
4134 commit 3414b17e9db16c3bc0de5b49555c4f94f155ffc8
4135 Author: Maciej W. Rozycki <macro@redhat.com>
4136 Date: Fri Jul 26 13:21:34 2024 +0100
4138 nptl: Use <support/check.h> facilities in tst-setuid3
4140 Remove local FAIL macro in favor to FAIL_EXIT1 from <support/check.h>,
4141 which provides equivalent reporting, with the name of the file and the
4142 line number within of the failure site additionally included. Remove
4143 FAIL_ERR altogether and include ": %m" explicitly with the format string
4144 supplied to FAIL_EXIT1 as there seems little value to have a separate
4145 macro just for this.
4147 Reviewed-by: DJ Delorie <dj@redhat.com>
4148 (cherry picked from commit 8c98195af6e6f1ce21743fc26c723e0f7e45bcf2)
4150 diff --git a/sysdeps/pthread/tst-setuid3.c b/sysdeps/pthread/tst-setuid3.c
4151 index 83f42a0ae5..3845ab03d3 100644
4152 --- a/sysdeps/pthread/tst-setuid3.c
4153 +++ b/sysdeps/pthread/tst-setuid3.c
4154 @@ -15,24 +15,19 @@
4155 License along with the GNU C Library; if not, see
4156 <https://www.gnu.org/licenses/>. */
4158 -#include <stdio.h>
4159 #include <errno.h>
4160 #include <pthread.h>
4161 #include <stdbool.h>
4162 #include <unistd.h>
4164 +#include <support/check.h>
4166 /* The test must run under a non-privileged user ID. */
4167 static const uid_t test_uid = 1;
4169 static pthread_barrier_t barrier1;
4170 static pthread_barrier_t barrier2;
4172 -#define FAIL(fmt, ...) \
4173 - do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0)
4175 -#define FAIL_ERR(fmt, ...) \
4176 - do { printf ("FAIL: " fmt ": %m\n", __VA_ARGS__); _exit (1); } while (0)
4178 /* True if x is not a successful return code from pthread_barrier_wait. */
4179 static inline bool
4180 is_invalid_barrier_ret (int x)
4181 @@ -45,10 +40,10 @@ thread_func (void *ctx __attribute__ ((unused)))
4183 int ret = pthread_barrier_wait (&barrier1);
4184 if (is_invalid_barrier_ret (ret))
4185 - FAIL ("pthread_barrier_wait (barrier1) (on thread): %d", ret);
4186 + FAIL_EXIT1 ("pthread_barrier_wait (barrier1) (on thread): %d", ret);
4187 ret = pthread_barrier_wait (&barrier2);
4188 if (is_invalid_barrier_ret (ret))
4189 - FAIL ("pthread_barrier_wait (barrier2) (on thread): %d", ret);
4190 + FAIL_EXIT1 ("pthread_barrier_wait (barrier2) (on thread): %d", ret);
4191 return NULL;
4194 @@ -59,13 +54,13 @@ setuid_failure (int phase)
4195 switch (ret)
4197 case 0:
4198 - FAIL ("setuid succeeded unexpectedly in phase %d", phase);
4199 + FAIL_EXIT1 ("setuid succeeded unexpectedly in phase %d", phase);
4200 case -1:
4201 if (errno != EPERM)
4202 - FAIL_ERR ("setuid phase %d", phase);
4203 + FAIL_EXIT1 ("setuid phase %d: %m", phase);
4204 break;
4205 default:
4206 - FAIL ("invalid setuid return value in phase %d: %d", phase, ret);
4207 + FAIL_EXIT1 ("invalid setuid return value in phase %d: %d", phase, ret);
4211 @@ -74,42 +69,42 @@ do_test (void)
4213 if (getuid () == 0)
4214 if (setuid (test_uid) != 0)
4215 - FAIL_ERR ("setuid (%u)", (unsigned) test_uid);
4216 + FAIL_EXIT1 ("setuid (%u): %m", (unsigned) test_uid);
4217 if (setuid (getuid ()))
4218 - FAIL_ERR ("setuid (%s)", "getuid ()");
4219 + FAIL_EXIT1 ("setuid (%s): %m", "getuid ()");
4220 setuid_failure (1);
4222 int ret = pthread_barrier_init (&barrier1, NULL, 2);
4223 if (ret != 0)
4224 - FAIL ("pthread_barrier_init (barrier1): %d", ret);
4225 + FAIL_EXIT1 ("pthread_barrier_init (barrier1): %d", ret);
4226 ret = pthread_barrier_init (&barrier2, NULL, 2);
4227 if (ret != 0)
4228 - FAIL ("pthread_barrier_init (barrier2): %d", ret);
4229 + FAIL_EXIT1 ("pthread_barrier_init (barrier2): %d", ret);
4231 pthread_t thread;
4232 ret = pthread_create (&thread, NULL, thread_func, NULL);
4233 if (ret != 0)
4234 - FAIL ("pthread_create: %d", ret);
4235 + FAIL_EXIT1 ("pthread_create: %d", ret);
4237 /* Ensure that the thread is running properly. */
4238 ret = pthread_barrier_wait (&barrier1);
4239 if (is_invalid_barrier_ret (ret))
4240 - FAIL ("pthread_barrier_wait (barrier1): %d", ret);
4241 + FAIL_EXIT1 ("pthread_barrier_wait (barrier1): %d", ret);
4243 setuid_failure (2);
4245 /* Check success case. */
4246 if (setuid (getuid ()) != 0)
4247 - FAIL_ERR ("setuid (%s)", "getuid ()");
4248 + FAIL_EXIT1 ("setuid (%s): %m", "getuid ()");
4250 /* Shutdown. */
4251 ret = pthread_barrier_wait (&barrier2);
4252 if (is_invalid_barrier_ret (ret))
4253 - FAIL ("pthread_barrier_wait (barrier2): %d", ret);
4254 + FAIL_EXIT1 ("pthread_barrier_wait (barrier2): %d", ret);
4256 ret = pthread_join (thread, NULL);
4257 if (ret != 0)
4258 - FAIL ("pthread_join: %d", ret);
4259 + FAIL_EXIT1 ("pthread_join: %d", ret);
4261 return 0;
4264 commit b7edcfa0f41ccfaeb665a661d3a6a594c8d95848
4265 Author: Florian Weimer <fweimer@redhat.com>
4266 Date: Thu Aug 1 23:31:23 2024 +0200
4268 elf: Clarify and invert second argument of _dl_allocate_tls_init
4270 Also remove an outdated comment: _dl_allocate_tls_init is
4271 called as part of pthread_create.
4273 Reviewed-by: Carlos O'Donell <carlos@redhat.com>
4274 (cherry picked from commit fe06fb313bddf7e4530056897d4a706606e49377)
4276 diff --git a/elf/dl-tls.c b/elf/dl-tls.c
4277 index 3d221273f1..ecb966d282 100644
4278 --- a/elf/dl-tls.c
4279 +++ b/elf/dl-tls.c
4280 @@ -552,9 +552,14 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
4281 /* Allocate initial TLS. RESULT should be a non-NULL pointer to storage
4282 for the TLS space. The DTV may be resized, and so this function may
4283 call malloc to allocate that space. The loader's GL(dl_load_tls_lock)
4284 - is taken when manipulating global TLS-related data in the loader. */
4285 + is taken when manipulating global TLS-related data in the loader.
4287 + If MAIN_THREAD, this is the first call during process
4288 + initialization. In this case, TLS initialization for secondary
4289 + (audit) namespaces is skipped because that has already been handled
4290 + by dlopen. */
4291 void *
4292 -_dl_allocate_tls_init (void *result, bool init_tls)
4293 +_dl_allocate_tls_init (void *result, bool main_thread)
4295 if (result == NULL)
4296 /* The memory allocation failed. */
4297 @@ -633,7 +638,7 @@ _dl_allocate_tls_init (void *result, bool init_tls)
4298 because it would already be set by the audit setup. However,
4299 subsequent thread creation would need to follow the default
4300 behaviour. */
4301 - if (map->l_ns != LM_ID_BASE && !init_tls)
4302 + if (map->l_ns != LM_ID_BASE && main_thread)
4303 continue;
4304 memset (__mempcpy (dest, map->l_tls_initimage,
4305 map->l_tls_initimage_size), '\0',
4306 @@ -661,7 +666,7 @@ _dl_allocate_tls (void *mem)
4308 return _dl_allocate_tls_init (mem == NULL
4309 ? _dl_allocate_tls_storage ()
4310 - : allocate_dtv (mem), true);
4311 + : allocate_dtv (mem), false);
4313 rtld_hidden_def (_dl_allocate_tls)
4315 diff --git a/elf/rtld.c b/elf/rtld.c
4316 index bfdf632e77..09b9c9993b 100644
4317 --- a/elf/rtld.c
4318 +++ b/elf/rtld.c
4319 @@ -2338,7 +2338,7 @@ dl_main (const ElfW(Phdr) *phdr,
4320 into the main thread's TLS area, which we allocated above.
4321 Note: thread-local variables must only be accessed after completing
4322 the next step. */
4323 - _dl_allocate_tls_init (tcbp, false);
4324 + _dl_allocate_tls_init (tcbp, true);
4326 /* And finally install it for the main thread. */
4327 if (! __rtld_tls_init_tp_called)
4328 diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
4329 index f35a8369bd..2cb562f8ea 100644
4330 --- a/nptl/allocatestack.c
4331 +++ b/nptl/allocatestack.c
4332 @@ -139,7 +139,7 @@ get_cached_stack (size_t *sizep, void **memp)
4333 memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
4335 /* Re-initialize the TLS. */
4336 - _dl_allocate_tls_init (TLS_TPADJ (result), true);
4337 + _dl_allocate_tls_init (TLS_TPADJ (result), false);
4339 return result;
4341 diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
4342 index 656e8a3fa0..154efb0e19 100644
4343 --- a/sysdeps/generic/ldsodefs.h
4344 +++ b/sysdeps/generic/ldsodefs.h
4345 @@ -1200,10 +1200,8 @@ extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp);
4347 extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
4349 -/* These are internal entry points to the two halves of _dl_allocate_tls,
4350 - only used within rtld.c itself at startup time. */
4351 extern void *_dl_allocate_tls_storage (void) attribute_hidden;
4352 -extern void *_dl_allocate_tls_init (void *, bool);
4353 +extern void *_dl_allocate_tls_init (void *result, bool main_thread);
4354 rtld_hidden_proto (_dl_allocate_tls_init)
4356 /* True if the TCB has been set up. */
4358 commit f496b750f135e57da921e975835c44bd199246dd
4359 Author: Florian Weimer <fweimer@redhat.com>
4360 Date: Thu Aug 1 23:31:30 2024 +0200
4362 elf: Avoid re-initializing already allocated TLS in dlopen (bug 31717)
4364 The old code used l_init_called as an indicator for whether TLS
4365 initialization was complete. However, it is possible that
4366 TLS for an object is initialized, written to, and then dlopen
4367 for this object is called again, and l_init_called is not true at
4368 this point. Previously, this resulted in TLS being initialized
4369 twice, discarding any interim writes (technically introducing a
4370 use-after-free bug even).
4372 This commit introduces an explicit per-object flag, l_tls_in_slotinfo.
4373 It indicates whether _dl_add_to_slotinfo has been called for this
4374 object. This flag is used to avoid double-initialization of TLS.
4375 In update_tls_slotinfo, the first_static_tls micro-optimization
4376 is removed because preserving the initalization flag for subsequent
4377 use by the second loop for static TLS is a bit complicated, and
4378 another per-object flag does not seem to be worth it. Furthermore,
4379 the l_init_called flag is dropped from the second loop (for static
4380 TLS initialization) because l_need_tls_init on its own prevents
4381 double-initialization.
4383 The remaining l_init_called usage in resize_scopes and update_scopes
4384 is just an optimization due to the use of scope_has_map, so it is
4385 not changed in this commit.
4387 The isupper check ensures that libc.so.6 is TLS is not reverted.
4388 Such a revert happens if l_need_tls_init is not cleared in
4389 _dl_allocate_tls_init for the main_thread case, now that
4390 l_init_called is not checked anymore in update_tls_slotinfo
4391 in elf/dl-open.c.
4393 Reported-by: Jonathon Anderson <janderson@rice.edu>
4394 Reviewed-by: Carlos O'Donell <carlos@redhat.com>
4395 (cherry picked from commit 5097cd344fd243fb8deb6dec96e8073753f962f9)
4397 diff --git a/NEWS b/NEWS
4398 index 10a125bc66..5b20efbf6c 100644
4399 --- a/NEWS
4400 +++ b/NEWS
4401 @@ -10,7 +10,7 @@ Version 2.40.1
4402 The following bugs are resolved with this release:
4404 [30081] resolv: Do not wait for non-existing second DNS response after error
4405 - [31968] mremap implementation in C does not handle arguments correctly
4406 + [31717] elf: Avoid re-initializing already allocated TLS in dlopen
4407 [31890] resolv: Allow short error responses to match any DNS query
4408 [31968] mremap implementation in C does not handle arguments correctly
4409 [32026] strerror/strsignal TLS not handled correctly for secondary namespaces
4410 diff --git a/elf/Makefile b/elf/Makefile
4411 index a3475f3fb5..a03c6520d8 100644
4412 --- a/elf/Makefile
4413 +++ b/elf/Makefile
4414 @@ -416,6 +416,10 @@ tests += \
4415 tst-dlmopen4 \
4416 tst-dlopen-self \
4417 tst-dlopen-tlsmodid \
4418 + tst-dlopen-tlsreinit1 \
4419 + tst-dlopen-tlsreinit2 \
4420 + tst-dlopen-tlsreinit3 \
4421 + tst-dlopen-tlsreinit4 \
4422 tst-dlopenfail \
4423 tst-dlopenfail-2 \
4424 tst-dlopenrpath \
4425 @@ -853,6 +857,9 @@ modules-names += \
4426 tst-dlmopen-twice-mod1 \
4427 tst-dlmopen-twice-mod2 \
4428 tst-dlmopen1mod \
4429 + tst-dlopen-tlsreinitmod1 \
4430 + tst-dlopen-tlsreinitmod2 \
4431 + tst-dlopen-tlsreinitmod3 \
4432 tst-dlopenfaillinkmod \
4433 tst-dlopenfailmod1 \
4434 tst-dlopenfailmod2 \
4435 @@ -3118,3 +3125,26 @@ $(objpfx)tst-recursive-tls.out: \
4436 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
4437 $(objpfx)tst-recursive-tlsmod%.os: tst-recursive-tlsmodN.c
4438 $(compile-command.c) -DVAR=thread_$* -DFUNC=get_threadvar_$*
4440 +# Order matters here. The test needs the constructor for
4441 +# tst-dlopen-tlsreinitmod2.so to be called first.
4442 +LDFLAGS-tst-dlopen-tlsreinitmod1.so = -Wl,--no-as-needed
4443 +$(objpfx)tst-dlopen-tlsreinitmod1.so: \
4444 + $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so
4445 +LDFLAGS-tst-dlopen-tlsreinit2 = -Wl,--no-as-needed
4446 +$(objpfx)tst-dlopen-tlsreinit2: \
4447 + $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so
4448 +LDFLAGS-tst-dlopen-tlsreinit4 = -Wl,--no-as-needed
4449 +$(objpfx)tst-dlopen-tlsreinit4: \
4450 + $(objpfx)tst-dlopen-tlsreinitmod3.so $(objpfx)tst-dlopen-tlsreinitmod2.so
4451 +# tst-dlopen-tlsreinitmod2.so is underlinked and refers to
4452 +# tst-dlopen-tlsreinitmod3.so. The dependency is provided via
4453 +# $(objpfx)tst-dlopen-tlsreinitmod1.so.
4454 +tst-dlopen-tlsreinitmod2.so-no-z-defs = yes
4455 +$(objpfx)tst-dlopen-tlsreinit.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \
4456 + $(objpfx)tst-dlopen-tlsreinitmod2.so $(objpfx)tst-dlopen-tlsreinitmod3.so
4457 +# Reuse an audit module which provides ample debug logging.
4458 +$(objpfx)tst-dlopen-tlsreinit3.out: $(objpfx)tst-auditmod1.so
4459 +tst-dlopen-tlsreinit3-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
4460 +$(objpfx)tst-dlopen-tlsreinit4.out: $(objpfx)tst-auditmod1.so
4461 +tst-dlopen-tlsreinit4-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
4462 diff --git a/elf/dl-open.c b/elf/dl-open.c
4463 index c378da16c0..8556e7bd2f 100644
4464 --- a/elf/dl-open.c
4465 +++ b/elf/dl-open.c
4466 @@ -363,17 +363,8 @@ resize_tls_slotinfo (struct link_map *new)
4468 bool any_tls = false;
4469 for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
4471 - struct link_map *imap = new->l_searchlist.r_list[i];
4473 - /* Only add TLS memory if this object is loaded now and
4474 - therefore is not yet initialized. */
4475 - if (! imap->l_init_called && imap->l_tls_blocksize > 0)
4477 - _dl_add_to_slotinfo (imap, false);
4478 - any_tls = true;
4481 + if (_dl_add_to_slotinfo (new->l_searchlist.r_list[i], false))
4482 + any_tls = true;
4483 return any_tls;
4486 @@ -383,22 +374,8 @@ resize_tls_slotinfo (struct link_map *new)
4487 static void
4488 update_tls_slotinfo (struct link_map *new)
4490 - unsigned int first_static_tls = new->l_searchlist.r_nlist;
4491 for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
4493 - struct link_map *imap = new->l_searchlist.r_list[i];
4495 - /* Only add TLS memory if this object is loaded now and
4496 - therefore is not yet initialized. */
4497 - if (! imap->l_init_called && imap->l_tls_blocksize > 0)
4499 - _dl_add_to_slotinfo (imap, true);
4501 - if (imap->l_need_tls_init
4502 - && first_static_tls == new->l_searchlist.r_nlist)
4503 - first_static_tls = i;
4506 + _dl_add_to_slotinfo (new->l_searchlist.r_list[i], true);
4508 size_t newgen = GL(dl_tls_generation) + 1;
4509 if (__glibc_unlikely (newgen == 0))
4510 @@ -410,13 +387,11 @@ TLS generation counter wrapped! Please report this."));
4511 /* We need a second pass for static tls data, because
4512 _dl_update_slotinfo must not be run while calls to
4513 _dl_add_to_slotinfo are still pending. */
4514 - for (unsigned int i = first_static_tls; i < new->l_searchlist.r_nlist; ++i)
4515 + for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
4517 struct link_map *imap = new->l_searchlist.r_list[i];
4519 - if (imap->l_need_tls_init
4520 - && ! imap->l_init_called
4521 - && imap->l_tls_blocksize > 0)
4522 + if (imap->l_need_tls_init && imap->l_tls_blocksize > 0)
4524 /* For static TLS we have to allocate the memory here and
4525 now, but we can delay updating the DTV. */
4526 diff --git a/elf/dl-tls.c b/elf/dl-tls.c
4527 index ecb966d282..3d529b722c 100644
4528 --- a/elf/dl-tls.c
4529 +++ b/elf/dl-tls.c
4530 @@ -632,17 +632,21 @@ _dl_allocate_tls_init (void *result, bool main_thread)
4531 some platforms use in static programs requires it. */
4532 dtv[map->l_tls_modid].pointer.val = dest;
4534 - /* Copy the initialization image and clear the BSS part. For
4535 - audit modules or dependencies with initial-exec TLS, we can not
4536 - set the initial TLS image on default loader initialization
4537 - because it would already be set by the audit setup. However,
4538 - subsequent thread creation would need to follow the default
4539 - behaviour. */
4540 + /* Copy the initialization image and clear the BSS part.
4541 + For audit modules or dependencies with initial-exec TLS,
4542 + we can not set the initial TLS image on default loader
4543 + initialization because it would already be set by the
4544 + audit setup, which uses the dlopen code and already
4545 + clears l_need_tls_init. Calls with !main_thread from
4546 + pthread_create need to initialze TLS for the current
4547 + thread regardless of namespace. */
4548 if (map->l_ns != LM_ID_BASE && main_thread)
4549 continue;
4550 memset (__mempcpy (dest, map->l_tls_initimage,
4551 map->l_tls_initimage_size), '\0',
4552 map->l_tls_blocksize - map->l_tls_initimage_size);
4553 + if (main_thread)
4554 + map->l_need_tls_init = 0;
4557 total += cnt;
4558 @@ -1099,9 +1103,32 @@ _dl_tls_initial_modid_limit_setup (void)
4562 -void
4563 +/* Add module to slot information data. If DO_ADD is false, only the
4564 + required memory is allocated. Must be called with
4565 + GL (dl_load_tls_lock) acquired. If the function has already been
4566 + called for the link map L with !DO_ADD, then this function will not
4567 + raise an exception, otherwise it is possible that it encounters a
4568 + memory allocation failure.
4570 + Return false if L has already been added to the slotinfo data, or
4571 + if L has no TLS data. If the returned value is true, L has been
4572 + added with this call (DO_ADD), or has been added in a previous call
4573 + (!DO_ADD).
4575 + The expected usage is as follows: Call _dl_add_to_slotinfo for
4576 + several link maps with DO_ADD set to false, and record if any calls
4577 + result in a true result. If there was a true result, call
4578 + _dl_add_to_slotinfo again, this time with DO_ADD set to true. (For
4579 + simplicity, it's possible to call the function for link maps where
4580 + the previous result was false.) The return value from the second
4581 + round of calls can be ignored. If there was true result initially,
4582 + call _dl_update_slotinfo to update the TLS generation counter. */
4583 +bool
4584 _dl_add_to_slotinfo (struct link_map *l, bool do_add)
4586 + if (l->l_tls_blocksize == 0 || l->l_tls_in_slotinfo)
4587 + return false;
4589 /* Now that we know the object is loaded successfully add
4590 modules containing TLS data to the dtv info table. We
4591 might have to increase its size. */
4592 @@ -1157,7 +1184,10 @@ cannot create TLS data structures"));
4593 atomic_store_relaxed (&listp->slotinfo[idx].map, l);
4594 atomic_store_relaxed (&listp->slotinfo[idx].gen,
4595 GL(dl_tls_generation) + 1);
4596 + l->l_tls_in_slotinfo = true;
4599 + return true;
4602 #if PTHREAD_IN_LIBC
4603 diff --git a/elf/tst-dlopen-tlsreinit1.c b/elf/tst-dlopen-tlsreinit1.c
4604 new file mode 100644
4605 index 0000000000..2016b9b0c6
4606 --- /dev/null
4607 +++ b/elf/tst-dlopen-tlsreinit1.c
4608 @@ -0,0 +1,40 @@
4609 +/* Test that dlopen preserves already accessed TLS (bug 31717).
4610 + Copyright (C) 2024 Free Software Foundation, Inc.
4611 + This file is part of the GNU C Library.
4613 + The GNU C Library is free software; you can redistribute it and/or
4614 + modify it under the terms of the GNU Lesser General Public
4615 + License as published by the Free Software Foundation; either
4616 + version 2.1 of the License, or (at your option) any later version.
4618 + The GNU C Library is distributed in the hope that it will be useful,
4619 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4620 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4621 + Lesser General Public License for more details.
4623 + You should have received a copy of the GNU Lesser General Public
4624 + License along with the GNU C Library; if not, see
4625 + <https://www.gnu.org/licenses/>. */
4627 +#include <stdbool.h>
4628 +#include <support/check.h>
4629 +#include <support/xdlfcn.h>
4630 +#include <ctype.h>
4632 +static int
4633 +do_test (void)
4635 + void *handle = xdlopen ("tst-dlopen-tlsreinitmod1.so", RTLD_NOW);
4637 + bool *tlsreinitmod3_tested = xdlsym (handle, "tlsreinitmod3_tested");
4638 + TEST_VERIFY (*tlsreinitmod3_tested);
4640 + xdlclose (handle);
4642 + /* This crashes if the libc.so.6 TLS image has been reverted. */
4643 + TEST_VERIFY (!isupper ('@'));
4645 + return 0;
4648 +#include <support/test-driver.c>
4649 diff --git a/elf/tst-dlopen-tlsreinit2.c b/elf/tst-dlopen-tlsreinit2.c
4650 new file mode 100644
4651 index 0000000000..90ad2c7713
4652 --- /dev/null
4653 +++ b/elf/tst-dlopen-tlsreinit2.c
4654 @@ -0,0 +1,39 @@
4655 +/* Test that dlopen preserves already accessed TLS (bug 31717).
4656 + Variant with initially-linked modules.
4657 + Copyright (C) 2024 Free Software Foundation, Inc.
4658 + This file is part of the GNU C Library.
4660 + The GNU C Library is free software; you can redistribute it and/or
4661 + modify it under the terms of the GNU Lesser General Public
4662 + License as published by the Free Software Foundation; either
4663 + version 2.1 of the License, or (at your option) any later version.
4665 + The GNU C Library is distributed in the hope that it will be useful,
4666 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4667 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4668 + Lesser General Public License for more details.
4670 + You should have received a copy of the GNU Lesser General Public
4671 + License along with the GNU C Library; if not, see
4672 + <https://www.gnu.org/licenses/>. */
4674 +#include <ctype.h>
4675 +#include <stdbool.h>
4676 +#include <support/check.h>
4677 +#include <support/xdlfcn.h>
4680 +static int
4681 +do_test (void)
4683 + /* Defined in tst-dlopen-tlsreinitmod3.so. */
4684 + extern bool tlsreinitmod3_tested;
4685 + TEST_VERIFY (tlsreinitmod3_tested);
4687 + /* This crashes if the libc.so.6 TLS image has been reverted. */
4688 + TEST_VERIFY (!isupper ('@'));
4690 + return 0;
4693 +#include <support/test-driver.c>
4694 diff --git a/elf/tst-dlopen-tlsreinit3.c b/elf/tst-dlopen-tlsreinit3.c
4695 new file mode 100644
4696 index 0000000000..79bd585aff
4697 --- /dev/null
4698 +++ b/elf/tst-dlopen-tlsreinit3.c
4699 @@ -0,0 +1,2 @@
4700 +/* Same code, but run with LD_AUDIT=tst-auditmod1.so. */
4701 +#include "tst-dlopen-tlsreinit1.c"
4702 diff --git a/elf/tst-dlopen-tlsreinit4.c b/elf/tst-dlopen-tlsreinit4.c
4703 new file mode 100644
4704 index 0000000000..344c9211ab
4705 --- /dev/null
4706 +++ b/elf/tst-dlopen-tlsreinit4.c
4707 @@ -0,0 +1,2 @@
4708 +/* Same code, but run with LD_AUDIT=tst-auditmod1.so. */
4709 +#include "tst-dlopen-tlsreinit2.c"
4710 diff --git a/elf/tst-dlopen-tlsreinitmod1.c b/elf/tst-dlopen-tlsreinitmod1.c
4711 new file mode 100644
4712 index 0000000000..354cc3de51
4713 --- /dev/null
4714 +++ b/elf/tst-dlopen-tlsreinitmod1.c
4715 @@ -0,0 +1,20 @@
4716 +/* Test that dlopen preserves already accessed TLS (bug 31717), module 1.
4717 + Copyright (C) 2024 Free Software Foundation, Inc.
4718 + This file is part of the GNU C Library.
4720 + The GNU C Library is free software; you can redistribute it and/or
4721 + modify it under the terms of the GNU Lesser General Public
4722 + License as published by the Free Software Foundation; either
4723 + version 2.1 of the License, or (at your option) any later version.
4725 + The GNU C Library is distributed in the hope that it will be useful,
4726 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4727 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4728 + Lesser General Public License for more details.
4730 + You should have received a copy of the GNU Lesser General Public
4731 + License along with the GNU C Library; if not, see
4732 + <https://www.gnu.org/licenses/>. */
4734 +/* This module triggers loading of tst-dlopen-tlsreinitmod2.so and
4735 + tst-dlopen-tlsreinitmod3.so. */
4736 diff --git a/elf/tst-dlopen-tlsreinitmod2.c b/elf/tst-dlopen-tlsreinitmod2.c
4737 new file mode 100644
4738 index 0000000000..677e69bd35
4739 --- /dev/null
4740 +++ b/elf/tst-dlopen-tlsreinitmod2.c
4741 @@ -0,0 +1,30 @@
4742 +/* Test that dlopen preserves already accessed TLS (bug 31717), module 2.
4743 + Copyright (C) 2024 Free Software Foundation, Inc.
4744 + This file is part of the GNU C Library.
4746 + The GNU C Library is free software; you can redistribute it and/or
4747 + modify it under the terms of the GNU Lesser General Public
4748 + License as published by the Free Software Foundation; either
4749 + version 2.1 of the License, or (at your option) any later version.
4751 + The GNU C Library is distributed in the hope that it will be useful,
4752 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4753 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4754 + Lesser General Public License for more details.
4756 + You should have received a copy of the GNU Lesser General Public
4757 + License along with the GNU C Library; if not, see
4758 + <https://www.gnu.org/licenses/>. */
4760 +#include <stdio.h>
4762 +/* Defined in tst-dlopen-tlsreinitmod3.so. This an underlinked symbol
4763 + dependency. */
4764 +extern void call_tlsreinitmod3 (void);
4766 +static void __attribute__ ((constructor))
4767 +tlsreinitmod2_init (void)
4769 + puts ("info: constructor of tst-dlopen-tlsreinitmod2.so invoked");
4770 + call_tlsreinitmod3 ();
4772 diff --git a/elf/tst-dlopen-tlsreinitmod3.c b/elf/tst-dlopen-tlsreinitmod3.c
4773 new file mode 100644
4774 index 0000000000..ef769c5131
4775 --- /dev/null
4776 +++ b/elf/tst-dlopen-tlsreinitmod3.c
4777 @@ -0,0 +1,102 @@
4778 +/* Test that dlopen preserves already accessed TLS (bug 31717), module 3.
4779 + Copyright (C) 2024 Free Software Foundation, Inc.
4780 + This file is part of the GNU C Library.
4782 + The GNU C Library is free software; you can redistribute it and/or
4783 + modify it under the terms of the GNU Lesser General Public
4784 + License as published by the Free Software Foundation; either
4785 + version 2.1 of the License, or (at your option) any later version.
4787 + The GNU C Library is distributed in the hope that it will be useful,
4788 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4789 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4790 + Lesser General Public License for more details.
4792 + You should have received a copy of the GNU Lesser General Public
4793 + License along with the GNU C Library; if not, see
4794 + <https://www.gnu.org/licenses/>. */
4796 +#include <dlfcn.h>
4797 +#include <stdbool.h>
4798 +#include <stdio.h>
4799 +#include <unistd.h>
4801 +/* Used to verify from the main program that the test ran. */
4802 +bool tlsreinitmod3_tested;
4804 +/* This TLS variable must not revert back to the initial state after
4805 + dlopen. */
4806 +static __thread int tlsreinitmod3_state = 1;
4808 +/* Set from the ELF constructor during dlopen. */
4809 +static bool tlsreinitmod3_constructed;
4811 +/* Second half of test, behind a compiler barrier. The compiler
4812 + barrier is necessary to prevent carrying over TLS address
4813 + information from call_tlsreinitmod3 to call_tlsreinitmod3_tail. */
4814 +void call_tlsreinitmod3_tail (void *self) __attribute__ ((weak));
4816 +/* Called from tst-dlopen-tlsreinitmod2.so. */
4817 +void
4818 +call_tlsreinitmod3 (void)
4820 + printf ("info: call_tlsreinitmod3 invoked (state=%d)\n",
4821 + tlsreinitmod3_state);
4823 + if (tlsreinitmod3_constructed)
4825 + puts ("error: call_tlsreinitmod3 called after ELF constructor");
4826 + fflush (stdout);
4827 + /* Cannot rely on test harness due to dynamic linking. */
4828 + _exit (1);
4831 + tlsreinitmod3_state = 2;
4833 + /* Self-dlopen. This will run the ELF constructor. */
4834 + void *self = dlopen ("tst-dlopen-tlsreinitmod3.so", RTLD_NOW);
4835 + if (self == NULL)
4837 + printf ("error: dlopen: %s\n", dlerror ());
4838 + fflush (stdout);
4839 + /* Cannot rely on test harness due to dynamic linking. */
4840 + _exit (1);
4843 + call_tlsreinitmod3_tail (self);
4846 +void
4847 +call_tlsreinitmod3_tail (void *self)
4849 + printf ("info: dlopen returned in tlsreinitmod3 (state=%d)\n",
4850 + tlsreinitmod3_state);
4852 + if (!tlsreinitmod3_constructed)
4854 + puts ("error: dlopen did not call tlsreinitmod3 ELF constructor");
4855 + fflush (stdout);
4856 + /* Cannot rely on test harness due to dynamic linking. */
4857 + _exit (1);
4860 + if (tlsreinitmod3_state != 2)
4862 + puts ("error: TLS state reverted in tlsreinitmod3");
4863 + fflush (stdout);
4864 + /* Cannot rely on test harness due to dynamic linking. */
4865 + _exit (1);
4868 + dlclose (self);
4870 + /* Signal test completion to the main program. */
4871 + tlsreinitmod3_tested = true;
4874 +static void __attribute__ ((constructor))
4875 +tlsreinitmod3_init (void)
4877 + puts ("info: constructor of tst-dlopen-tlsreinitmod3.so invoked");
4878 + tlsreinitmod3_constructed = true;
4880 diff --git a/include/link.h b/include/link.h
4881 index cb0d7d8e2f..5ed445d5a6 100644
4882 --- a/include/link.h
4883 +++ b/include/link.h
4884 @@ -212,6 +212,7 @@ struct link_map
4885 unsigned int l_find_object_processed:1; /* Zero if _dl_find_object_update
4886 needs to process this
4887 lt_library map. */
4888 + unsigned int l_tls_in_slotinfo:1; /* TLS slotinfo updated in dlopen. */
4890 /* NODELETE status of the map. Only valid for maps of type
4891 lt_loaded. Lazy binding sets l_nodelete_active directly,
4892 diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
4893 index 154efb0e19..259ce2e7d6 100644
4894 --- a/sysdeps/generic/ldsodefs.h
4895 +++ b/sysdeps/generic/ldsodefs.h
4896 @@ -1239,13 +1239,7 @@ extern void *_dl_open (const char *name, int mode, const void *caller,
4897 extern int _dl_scope_free (void *) attribute_hidden;
4900 -/* Add module to slot information data. If DO_ADD is false, only the
4901 - required memory is allocated. Must be called with GL
4902 - (dl_load_tls_lock) acquired. If the function has already been called
4903 - for the link map L with !do_add, then this function will not raise
4904 - an exception, otherwise it is possible that it encounters a memory
4905 - allocation failure. */
4906 -extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add)
4907 +extern bool _dl_add_to_slotinfo (struct link_map *l, bool do_add)
4908 attribute_hidden;
4910 /* Update slot information data for at least the generation of the
4912 commit f4a9b6e97bf05cf5a41907e55901f7e9afaafd4d
4913 Author: Florian Weimer <fweimer@redhat.com>
4914 Date: Mon Sep 9 21:10:23 2024 +0200
4916 elf: Fix tst-dlopen-tlsreinit1.out test dependency
4918 Fixes commit 5097cd344fd243fb8deb6dec96e8073753f962f9
4919 ("elf: Avoid re-initializing already allocated TLS in dlopen
4920 (bug 31717)").
4922 Reported-by: Patsy Griffin <patsy@redhat.com>
4923 Reviewed-by: Patsy Griffin <patsy@redhat.com>
4924 (cherry picked from commit e82a7cb1622bff08d8e3a144d7c5516a088f1cbc)
4926 diff --git a/elf/Makefile b/elf/Makefile
4927 index a03c6520d8..dc686c3bff 100644
4928 --- a/elf/Makefile
4929 +++ b/elf/Makefile
4930 @@ -3141,7 +3141,7 @@ $(objpfx)tst-dlopen-tlsreinit4: \
4931 # tst-dlopen-tlsreinitmod3.so. The dependency is provided via
4932 # $(objpfx)tst-dlopen-tlsreinitmod1.so.
4933 tst-dlopen-tlsreinitmod2.so-no-z-defs = yes
4934 -$(objpfx)tst-dlopen-tlsreinit.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \
4935 +$(objpfx)tst-dlopen-tlsreinit1.out: $(objpfx)tst-dlopen-tlsreinitmod1.so \
4936 $(objpfx)tst-dlopen-tlsreinitmod2.so $(objpfx)tst-dlopen-tlsreinitmod3.so
4937 # Reuse an audit module which provides ample debug logging.
4938 $(objpfx)tst-dlopen-tlsreinit3.out: $(objpfx)tst-auditmod1.so
4940 commit adfb14e71f240a6bc2a4cbd6e6c50cc3fa1bcc3b
4941 Author: Florian Weimer <fweimer@redhat.com>
4942 Date: Tue Sep 10 12:40:27 2024 +0200
4944 debug: Fix read error handling in pcprofiledump
4946 The reading loops did not check for read failures. Addresses
4947 a static analysis report.
4949 Manually tested by compiling a program with the GCC's
4950 -finstrument-functions option, running it with
4951 “LD_PRELOAD=debug/libpcprofile.so PCPROFILE_OUTPUT=output-file”,
4952 and reviewing the output of “debug/pcprofiledump output-file”.
4954 (cherry picked from commit 89b088bf70c651c231bf27e644270d093b8f144a)
4956 diff --git a/debug/pcprofiledump.c b/debug/pcprofiledump.c
4957 index 049a9c2744..94530f0cf9 100644
4958 --- a/debug/pcprofiledump.c
4959 +++ b/debug/pcprofiledump.c
4960 @@ -75,6 +75,44 @@ static struct argp argp =
4961 options, parse_opt, args_doc, doc, NULL, more_help
4964 +/* Try to read SIZE bytes from FD and store them on BUF. Terminate
4965 + the process upon read error. Also terminate the process if less
4966 + than SIZE bytes are remaining in the file. If !IN_HEADER, do not
4967 + terminate the process if the end of the file is encountered
4968 + immediately, before any bytes are read.
4970 + Returns true if SIZE bytes have been read, and false if no bytes
4971 + have been read due to an end-of-file condition. */
4972 +static bool
4973 +read_exactly (int fd, void *buffer, size_t size, bool in_header)
4975 + char *p = buffer;
4976 + char *end = p + size;
4977 + while (p < end)
4979 + ssize_t ret = TEMP_FAILURE_RETRY (read (fd, p, end - p));
4980 + if (ret < 0)
4982 + if (in_header)
4983 + error (EXIT_FAILURE, errno, _("cannot read header"));
4984 + else
4985 + error (EXIT_FAILURE, errno, _("cannot read pointer pair"));
4987 + if (ret == 0)
4989 + if (p == buffer && !in_header)
4990 + /* Nothing has been read. */
4991 + return false;
4992 + if (in_header)
4993 + error (EXIT_FAILURE, 0, _("unexpected end of file in header"));
4994 + else
4995 + error (EXIT_FAILURE, 0,
4996 + _("unexpected end of file in pointer pair"));
4998 + p += ret;
5000 + return true;
5004 main (int argc, char *argv[])
5005 @@ -110,8 +148,7 @@ main (int argc, char *argv[])
5006 /* Read the first 4-byte word. It contains the information about
5007 the word size and the endianness. */
5008 uint32_t word;
5009 - if (TEMP_FAILURE_RETRY (read (fd, &word, 4)) != 4)
5010 - error (EXIT_FAILURE, errno, _("cannot read header"));
5011 + read_exactly (fd, &word, sizeof (word), true);
5013 /* Check whether we have to swap the byte order. */
5014 int must_swap = (word & 0x0fffffff) == bswap_32 (0xdeb00000);
5015 @@ -121,56 +158,30 @@ main (int argc, char *argv[])
5016 /* We have two loops, one for 32 bit pointers, one for 64 bit pointers. */
5017 if (word == 0xdeb00004)
5019 - union
5021 - uint32_t ptrs[2];
5022 - char bytes[8];
5023 - } pair;
5024 + uint32_t ptrs[2];
5026 while (1)
5028 - size_t len = sizeof (pair);
5029 - size_t n;
5031 - while (len > 0
5032 - && (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len],
5033 - len))) != 0)
5034 - len -= n;
5036 - if (len != 0)
5037 - /* Nothing to read. */
5038 + if (!read_exactly (fd, ptrs, sizeof (ptrs), false))
5039 break;
5041 printf ("this = %#010" PRIx32 ", caller = %#010" PRIx32 "\n",
5042 - must_swap ? bswap_32 (pair.ptrs[0]) : pair.ptrs[0],
5043 - must_swap ? bswap_32 (pair.ptrs[1]) : pair.ptrs[1]);
5044 + must_swap ? bswap_32 (ptrs[0]) : ptrs[0],
5045 + must_swap ? bswap_32 (ptrs[1]) : ptrs[1]);
5048 else if (word == 0xdeb00008)
5050 - union
5052 - uint64_t ptrs[2];
5053 - char bytes[16];
5054 - } pair;
5055 + uint64_t ptrs[2];
5057 while (1)
5059 - size_t len = sizeof (pair);
5060 - size_t n;
5062 - while (len > 0
5063 - && (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len],
5064 - len))) != 0)
5065 - len -= n;
5067 - if (len != 0)
5068 - /* Nothing to read. */
5069 + if (!read_exactly (fd, ptrs, sizeof (ptrs), false))
5070 break;
5072 printf ("this = %#018" PRIx64 ", caller = %#018" PRIx64 "\n",
5073 - must_swap ? bswap_64 (pair.ptrs[0]) : pair.ptrs[0],
5074 - must_swap ? bswap_64 (pair.ptrs[1]) : pair.ptrs[1]);
5075 + must_swap ? bswap_64 (ptrs[0]) : ptrs[0],
5076 + must_swap ? bswap_64 (ptrs[1]) : ptrs[1]);
5079 else
5081 commit 7073164add3b874cf0c19ca0fb84236f6bb0985d
5082 Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
5083 Date: Tue Sep 3 14:58:33 2024 -0400
5085 libio: Attempt wide backup free only for non-legacy code
5087 _wide_data and _mode are not available in legacy code, so do not attempt
5088 to free the wide backup buffer in legacy code.
5090 Resolves: BZ #32137 and BZ #27821
5092 Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
5093 Reviewed-by: Florian Weimer <fweimer@redhat.com>
5094 (cherry picked from commit ae4d44b1d501421ad9a3af95279b8f4d1546f1ce)
5096 diff --git a/NEWS b/NEWS
5097 index 5b20efbf6c..9033335db1 100644
5098 --- a/NEWS
5099 +++ b/NEWS
5100 @@ -9,12 +9,14 @@ Version 2.40.1
5102 The following bugs are resolved with this release:
5104 + [27821] ungetc: Fix backup buffer leak on program exit
5105 [30081] resolv: Do not wait for non-existing second DNS response after error
5106 [31717] elf: Avoid re-initializing already allocated TLS in dlopen
5107 [31890] resolv: Allow short error responses to match any DNS query
5108 [31968] mremap implementation in C does not handle arguments correctly
5109 [32026] strerror/strsignal TLS not handled correctly for secondary namespaces
5110 [32052] Name space violation in fortify wrappers
5111 + [32137] libio: Attempt wide backup free only for non-legacy code
5113 Version 2.40
5115 diff --git a/libio/genops.c b/libio/genops.c
5116 index 35d8b30710..6f20d49669 100644
5117 --- a/libio/genops.c
5118 +++ b/libio/genops.c
5119 @@ -819,7 +819,7 @@ _IO_unbuffer_all (void)
5120 /* Free up the backup area if it was ever allocated. */
5121 if (_IO_have_backup (fp))
5122 _IO_free_backup_area (fp);
5123 - if (fp->_mode > 0 && _IO_have_wbackup (fp))
5124 + if (!legacy && fp->_mode > 0 && _IO_have_wbackup (fp))
5125 _IO_free_wbackup_area (fp);
5127 if (! (fp->_flags & _IO_UNBUFFERED)