Gentoo Archives: gentoo-commits

From: "Andreas K. Hüttel" <dilfridge@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/toolchain/glibc-patches:master commit in: 9999/
Date: Wed, 01 Feb 2023 19:47:04
Message-Id: 1675280679.4e94f64bd9462f55e52de64d1c49b20cdfc686a3.dilfridge@gentoo
1 commit: 4e94f64bd9462f55e52de64d1c49b20cdfc686a3
2 Author: Andreas K. Hüttel <dilfridge <AT> gentoo <DOT> org>
3 AuthorDate: Wed Feb 1 19:44:39 2023 +0000
4 Commit: Andreas K. Hüttel <dilfridge <AT> gentoo <DOT> org>
5 CommitDate: Wed Feb 1 19:44:39 2023 +0000
6 URL: https://gitweb.gentoo.org/proj/toolchain/glibc-patches.git/commit/?id=4e94f64b
7
8 Update dirent-related patchset from libc-alpha archive (v5)
9
10 Signed-off-by: Andreas K. Hüttel <dilfridge <AT> gentoo.org>
11
12 9999/0001-Disable-ldconfig-during-install.patch | 8 +-
13 ...Adapt-to-Gentoo-specific-etc-mail-aliases.patch | 12 +-
14 ...O0-in-conform-tests-to-survive-CC-changes.patch | 10 +-
15 .../0004-Fix-miscompilation-on-ia64-s-gcc-10.patch | 8 +-
16 ...5-linux-Use-getdents64-on-non-LFS-readdir.patch | 190 +++----
17 ...nternal-DIR-filepos-as-off64_t-BZ-23960-B.patch | 616 +++++++++++----------
18 9999/0007-linux-Add-__readdir64_unlocked.patch | 14 +-
19 9999/0008-linux-Add-__old_readdir64_unlocked.patch | 14 +-
20 ...etdents64-on-readdir64-compat-implementat.patch | 123 ++--
21 9999/0010-dirent-Deprecate-getdirentries.patch | 100 ----
22 10 files changed, 500 insertions(+), 595 deletions(-)
23
24 diff --git a/9999/0001-Disable-ldconfig-during-install.patch b/9999/0001-Disable-ldconfig-during-install.patch
25 index 4a8c771..e947fac 100644
26 --- a/9999/0001-Disable-ldconfig-during-install.patch
27 +++ b/9999/0001-Disable-ldconfig-during-install.patch
28 @@ -1,7 +1,7 @@
29 -From 5349895a928bff28939b228824c8265d20d9fa60 Mon Sep 17 00:00:00 2001
30 +From 3b59ad9dec2c1c7f1b4c7f72d14ea3f2b68a4eca Mon Sep 17 00:00:00 2001
31 From: Mike Frysinger <vapier@g.o>
32 Date: Tue, 3 Aug 2021 00:34:59 +0200
33 -Subject: [PATCH 01/10] Disable ldconfig during install
34 +Subject: [PATCH 1/9] Disable ldconfig during install
35 MIME-Version: 1.0
36 Content-Type: text/plain; charset=UTF-8
37 Content-Transfer-Encoding: 8bit
38 @@ -19,7 +19,7 @@ Signed-off-by: Andreas K. Hüttel <dilfridge@g.o>
39 1 file changed, 1 insertion(+)
40
41 diff --git a/Makefile b/Makefile
42 -index 179dd478ff..763d6a084a 100644
43 +index 224c792185..be9df042e0 100644
44 --- a/Makefile
45 +++ b/Makefile
46 @@ -110,6 +110,7 @@ elf/ldso_install:
47 @@ -31,5 +31,5 @@ index 179dd478ff..763d6a084a 100644
48 $(elf-objpfx)ldconfig $(addprefix -r ,$(install_root)) \
49 $(slibdir) $(libdir)
50 --
51 -2.38.2
52 +2.39.1
53
54
55 diff --git a/9999/0002-Adapt-to-Gentoo-specific-etc-mail-aliases.patch b/9999/0002-Adapt-to-Gentoo-specific-etc-mail-aliases.patch
56 index 559e736..09c2dde 100644
57 --- a/9999/0002-Adapt-to-Gentoo-specific-etc-mail-aliases.patch
58 +++ b/9999/0002-Adapt-to-Gentoo-specific-etc-mail-aliases.patch
59 @@ -1,7 +1,7 @@
60 -From ab1ca71990a972e375709711f5fa268010505324 Mon Sep 17 00:00:00 2001
61 +From d8a45f4bfa30b502647a9ef742836c7e8694d009 Mon Sep 17 00:00:00 2001
62 From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= <dilfridge@g.o>
63 Date: Mon, 22 Oct 2018 22:34:13 +0200
64 -Subject: [PATCH 02/10] Adapt to Gentoo-specific /etc/mail/aliases
65 +Subject: [PATCH 2/9] Adapt to Gentoo-specific /etc/mail/aliases
66 MIME-Version: 1.0
67 Content-Type: text/plain; charset=UTF-8
68 Content-Transfer-Encoding: 8bit
69 @@ -18,7 +18,7 @@ Signed-off-by: Andreas K. Hüttel <dilfridge@g.o>
70 3 files changed, 17 insertions(+), 11 deletions(-)
71
72 diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
73 -index 505721388f..44d835cace 100644
74 +index 1c32884fe7..f40fd19288 100644
75 --- a/nss/nss_files/files-alias.c
76 +++ b/nss/nss_files/files-alias.c
77 @@ -42,7 +42,7 @@ internal_setent (FILE **stream)
78 @@ -31,7 +31,7 @@ index 505721388f..44d835cace 100644
79 if (*stream == NULL)
80 status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
81 diff --git a/nss/tst-nss-files-alias-leak.c b/nss/tst-nss-files-alias-leak.c
82 -index 576f07fa0a..29962764e2 100644
83 +index a62e137614..f0cd132ce6 100644
84 --- a/nss/tst-nss-files-alias-leak.c
85 +++ b/nss/tst-nss-files-alias-leak.c
86 @@ -45,27 +45,27 @@ prepare (int argc, char **argv)
87 @@ -80,7 +80,7 @@ index 576f07fa0a..29962764e2 100644
88 FILE *fp = xfopen (path, "w");
89 for (int i = 0; i < many_aliases; ++i)
90 diff --git a/support/support_chroot.c b/support/support_chroot.c
91 -index 4bf6fe0834..1548eba2ad 100644
92 +index 7a1b7272f0..500c9a79a3 100644
93 --- a/support/support_chroot.c
94 +++ b/support/support_chroot.c
95 @@ -52,13 +52,19 @@ support_chroot_create (struct support_chroot_configuration conf)
96 @@ -105,5 +105,5 @@ index 4bf6fe0834..1548eba2ad 100644
97 /* valgrind needs a temporary directory in the chroot. */
98 {
99 --
100 -2.38.2
101 +2.39.1
102
103
104 diff --git a/9999/0003-Force-O0-in-conform-tests-to-survive-CC-changes.patch b/9999/0003-Force-O0-in-conform-tests-to-survive-CC-changes.patch
105 index f662cda..ac36f58 100644
106 --- a/9999/0003-Force-O0-in-conform-tests-to-survive-CC-changes.patch
107 +++ b/9999/0003-Force-O0-in-conform-tests-to-survive-CC-changes.patch
108 @@ -1,7 +1,7 @@
109 -From f44c6c3768c2a3ef274782a2e308fb6b8fe84499 Mon Sep 17 00:00:00 2001
110 +From d2b4275295e9c5a312063c3bce663ae1dcf754f0 Mon Sep 17 00:00:00 2001
111 From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= <dilfridge@g.o>
112 Date: Fri, 14 Dec 2018 20:43:04 +0100
113 -Subject: [PATCH 03/10] Force -O0 in conform tests to survive $CC changes
114 +Subject: [PATCH 3/9] Force -O0 in conform tests to survive $CC changes
115 MIME-Version: 1.0
116 Content-Type: text/plain; charset=UTF-8
117 Content-Transfer-Encoding: 8bit
118 @@ -22,7 +22,7 @@ Signed-off-by: Andreas K. Hüttel <dilfridge@g.o>
119 2 files changed, 7 insertions(+), 3 deletions(-)
120
121 diff --git a/conform/conformtest.py b/conform/conformtest.py
122 -index 94a7ee110f..90c81ac88e 100644
123 +index 124860da01..8b1643a097 100644
124 --- a/conform/conformtest.py
125 +++ b/conform/conformtest.py
126 @@ -566,7 +566,7 @@ class HeaderTests(object):
127 @@ -46,7 +46,7 @@ index 94a7ee110f..90c81ac88e 100644
128 subprocess.check_call(cmd, shell=True)
129 bad_tokens = set()
130 diff --git a/conform/linknamespace.py b/conform/linknamespace.py
131 -index f7fe3a7a0a..ad87fd2a6d 100644
132 +index 983bba1bd2..b6fce8a21c 100644
133 --- a/conform/linknamespace.py
134 +++ b/conform/linknamespace.py
135 @@ -157,7 +157,9 @@ def main():
136 @@ -61,5 +61,5 @@ index f7fe3a7a0a..ad87fd2a6d 100644
137 args.header)
138 with tempfile.TemporaryDirectory() as temp_dir:
139 --
140 -2.38.2
141 +2.39.1
142
143
144 diff --git a/9999/0004-Fix-miscompilation-on-ia64-s-gcc-10.patch b/9999/0004-Fix-miscompilation-on-ia64-s-gcc-10.patch
145 index 2d9c8f7..215b5fa 100644
146 --- a/9999/0004-Fix-miscompilation-on-ia64-s-gcc-10.patch
147 +++ b/9999/0004-Fix-miscompilation-on-ia64-s-gcc-10.patch
148 @@ -1,7 +1,7 @@
149 -From 4aafe3fae7777fec09e2dd3915a8fd33642bba94 Mon Sep 17 00:00:00 2001
150 +From 7a2ab3f8d680338aff2559541a4bb748618e16f6 Mon Sep 17 00:00:00 2001
151 From: Sergei Trofimovich <slyfox@g.o>
152 Date: Sat, 11 Jul 2020 20:06:51 +0300
153 -Subject: [PATCH 04/10] Fix miscompilation on ia64's gcc-10
154 +Subject: [PATCH 4/9] Fix miscompilation on ia64's gcc-10
155 MIME-Version: 1.0
156 Content-Type: text/plain; charset=UTF-8
157 Content-Transfer-Encoding: 8bit
158 @@ -13,7 +13,7 @@ Signed-off-by: Andreas K. Hüttel <dilfridge@g.o>
159 1 file changed, 3 insertions(+), 1 deletion(-)
160
161 diff --git a/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
162 -index aa1de6b361..f6472f1942 100644
163 +index 3e4d5da820..eb7681b704 100644
164 --- a/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
165 +++ b/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
166 @@ -32,7 +32,9 @@
167 @@ -28,5 +28,5 @@ index aa1de6b361..f6472f1942 100644
168 # define DL_SYSINFO_IMPLEMENTATION \
169 asm (".text\n\t" \
170 --
171 -2.38.2
172 +2.39.1
173
174
175 diff --git a/9999/0005-linux-Use-getdents64-on-non-LFS-readdir.patch b/9999/0005-linux-Use-getdents64-on-non-LFS-readdir.patch
176 index 4e1dc0d..4cb21bf 100644
177 --- a/9999/0005-linux-Use-getdents64-on-non-LFS-readdir.patch
178 +++ b/9999/0005-linux-Use-getdents64-on-non-LFS-readdir.patch
179 @@ -1,127 +1,109 @@
180 -From 0718c1ca37fe6407bd4bad15dfae873719eabb6e Mon Sep 17 00:00:00 2001
181 +From 1652c61d24e43a0efd1fd4812f4a67494d093cc2 Mon Sep 17 00:00:00 2001
182 From: Adhemerval Zanella <adhemerval.zanella@××××××.org>
183 -Date: Tue, 20 Oct 2020 13:37:15 -0300
184 -Subject: [PATCH 05/10] linux: Use getdents64 on non-LFS readdir
185 +Date: Fri, 27 Jan 2023 14:28:30 -0300
186 +Subject: [PATCH 5/9] linux: Use getdents64 on non-LFS readdir
187
188 -The opendir allocates a translation buffer to be used to return the
189 -non-LFS readdir entry. The obtained dirent64 struct is translated
190 -to the temporary buffer on each readdir call.
191 +The non-LFS opendir reserves a translation entry to be used to return
192 +the entry and the dirent64 struct is translated to the temporary buffer
193 +on each readdir call.
194
195 Entries that overflow d_off/d_ino and the buffer reallocation failure
196 (in case of large d_name) are ignored.
197
198 Checked on x86_64-linux-gnu and i686-linux-gnu.
199 ---
200 - sysdeps/unix/sysv/linux/closedir.c | 4 ++
201 + dirent/tst-scandir.c | 6 ++-
202 + include/dirent.h | 2 +-
203 sysdeps/unix/sysv/linux/dirstream.h | 5 ++
204 - sysdeps/unix/sysv/linux/opendir.c | 21 +++++++
205 - sysdeps/unix/sysv/linux/readdir.c | 94 +++++++++++++++++++++--------
206 - 4 files changed, 98 insertions(+), 26 deletions(-)
207 + sysdeps/unix/sysv/linux/readdir.c | 83 +++++++++++++++++++----------
208 + 4 files changed, 67 insertions(+), 29 deletions(-)
209
210 -diff --git a/sysdeps/unix/sysv/linux/closedir.c b/sysdeps/unix/sysv/linux/closedir.c
211 -index eee0193fc4..d876d49d78 100644
212 ---- a/sysdeps/unix/sysv/linux/closedir.c
213 -+++ b/sysdeps/unix/sysv/linux/closedir.c
214 -@@ -47,6 +47,10 @@ __closedir (DIR *dirp)
215 - __libc_lock_fini (dirp->lock);
216 - #endif
217 -
218 -+#if !_DIRENT_MATCHES_DIRENT64
219 -+ free (dirp->tbuffer);
220 -+#endif
221 -+
222 - free ((void *) dirp);
223 +diff --git a/dirent/tst-scandir.c b/dirent/tst-scandir.c
224 +index 8d87d4dd74..7bc666449e 100644
225 +--- a/dirent/tst-scandir.c
226 ++++ b/dirent/tst-scandir.c
227 +@@ -155,8 +155,12 @@ do_test (void)
228 + }
229 + if (n != 6)
230 + {
231 ++ /* Non-lfs opendir skips entries that can not be represented (for
232 ++ instance if d_off is not an offset but rather an internal filesystem
233 ++ representation. For this case there is no point in continue the
234 ++ testcase. */
235 + printf ("scandir returned %d entries instead of 6\n", n);
236 +- return 1;
237 ++ return EXIT_UNSUPPORTED;
238 + }
239
240 - return __close_nocancel (fd);
241 + struct
242 +diff --git a/include/dirent.h b/include/dirent.h
243 +index d7567f5e86..17827176ba 100644
244 +--- a/include/dirent.h
245 ++++ b/include/dirent.h
246 +@@ -1,8 +1,8 @@
247 + #ifndef _DIRENT_H
248 ++# include <dirent/dirent.h>
249 + # ifndef _ISOMAC
250 + # include <dirstream.h>
251 + # endif
252 +-# include <dirent/dirent.h>
253 + # ifndef _ISOMAC
254 + # include <sys/stat.h>
255 + # include <stdbool.h>
256 diff --git a/sysdeps/unix/sysv/linux/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h
257 -index a0d8acf08d..064273cc31 100644
258 +index 3cb313b410..adcf8234f1 100644
259 --- a/sysdeps/unix/sysv/linux/dirstream.h
260 +++ b/sysdeps/unix/sysv/linux/dirstream.h
261 -@@ -41,6 +41,11 @@ struct __dirstream
262 +@@ -18,6 +18,7 @@
263 + #ifndef _DIRSTREAM_H
264 + #define _DIRSTREAM_H 1
265 +
266 ++#include <dirent.h>
267 + #include <sys/types.h>
268 +
269 + #include <libc-lock.h>
270 +@@ -41,6 +42,10 @@ struct __dirstream
271
272 int errcode; /* Delayed error code. */
273
274 +#if !defined __OFF_T_MATCHES_OFF64_T || !defined __INO_T_MATCHES_INO64_T
275 -+ char *tbuffer; /* Translation buffer for non-LFS calls. */
276 -+ size_t tbuffer_size; /* Size of translation buffer. */
277 ++ struct dirent tdp;
278 +#endif
279 +
280 /* Directory block. We must make sure that this block starts
281 at an address that is aligned adequately enough to store
282 dirent entries. Using the alignment of "void *" is not
283 -diff --git a/sysdeps/unix/sysv/linux/opendir.c b/sysdeps/unix/sysv/linux/opendir.c
284 -index 9e81d00630..bfd2f382a6 100644
285 ---- a/sysdeps/unix/sysv/linux/opendir.c
286 -+++ b/sysdeps/unix/sysv/linux/opendir.c
287 -@@ -120,6 +120,27 @@ __alloc_dir (int fd, bool close_fd, int flags,
288 - return NULL;
289 - }
290 -
291 -+#if !_DIRENT_MATCHES_DIRENT64
292 -+ /* Allocates a translation buffer to use as the returned 'struct direct'
293 -+ for non-LFS 'readdir' calls.
294 -+
295 -+ The initial NAME_MAX size should handle most cases, while readdir might
296 -+ expand the buffer if required. */
297 -+ enum
298 -+ {
299 -+ tbuffer_size = sizeof (struct dirent) + NAME_MAX + 1
300 -+ };
301 -+ dirp->tbuffer = malloc (tbuffer_size);
302 -+ if (dirp->tbuffer == NULL)
303 -+ {
304 -+ free (dirp);
305 -+ if (close_fd)
306 -+ __close_nocancel_nostatus (fd);
307 -+ return NULL;
308 -+ }
309 -+ dirp->tbuffer_size = tbuffer_size;
310 -+#endif
311 -+
312 - dirp->fd = fd;
313 - #if IS_IN (libc)
314 - __libc_lock_init (dirp->lock);
315 diff --git a/sysdeps/unix/sysv/linux/readdir.c b/sysdeps/unix/sysv/linux/readdir.c
316 -index c9a04dc160..c078146d7d 100644
317 +index 4a4c00ea07..cd0ccaf33a 100644
318 --- a/sysdeps/unix/sysv/linux/readdir.c
319 +++ b/sysdeps/unix/sysv/linux/readdir.c
320 -@@ -21,42 +21,84 @@
321 +@@ -21,42 +21,71 @@
322 #if !_DIRENT_MATCHES_DIRENT64
323 #include <dirstream.h>
324
325 -+/* Translate the DP64 entry to the non-LFS one in the translation buffer
326 ++/* Translate the DP64 entry to the non-LFS one in the translation entry
327 + at dirstream DS. Return true is the translation was possible or
328 -+ false if either an internal fields can be represented in the non-LFS
329 -+ entry or if the translation can not be resized. */
330 ++ false if either an internal field can not be represented in the non-LFS
331 ++ entry or if the name is too long. */
332 +static bool
333 +dirstream_entry (struct __dirstream *ds, const struct dirent64 *dp64)
334 +{
335 -+ off_t d_off = dp64->d_off;
336 -+ if (d_off != dp64->d_off)
337 -+ return false;
338 -+ ino_t d_ino = dp64->d_ino;
339 -+ if (d_ino != dp64->d_ino)
340 ++ /* Check for overflow. */
341 ++ if (!in_off_t_range (dp64->d_off) || !in_ino_t_range (dp64->d_ino))
342 + return false;
343 +
344 -+ /* Expand the translation buffer to hold the new name size. */
345 -+ size_t new_reclen = sizeof (struct dirent)
346 -+ + dp64->d_reclen - offsetof (struct dirent64, d_name);
347 -+ if (new_reclen > ds->tbuffer_size)
348 -+ {
349 -+ char *newbuffer = realloc (ds->tbuffer, new_reclen);
350 -+ if (newbuffer == NULL)
351 -+ return false;
352 -+ ds->tbuffer = newbuffer;
353 -+ ds->tbuffer_size = new_reclen;
354 -+ }
355 ++ /* And if name is too large. */
356 ++ if (dp64->d_reclen - offsetof (struct dirent64, d_name) > NAME_MAX)
357 ++ return false;
358 +
359 -+ struct dirent *dp = (struct dirent *) ds->tbuffer;
360 ++ ds->filepos = dp64->d_off;
361 +
362 -+ dp->d_off = d_off;
363 -+ dp->d_ino = d_ino;
364 -+ dp->d_reclen = new_reclen;
365 -+ dp->d_type = dp64->d_type;
366 -+ memcpy (dp->d_name, dp64->d_name,
367 ++ ds->tdp.d_off = dp64->d_off;
368 ++ ds->tdp.d_ino = dp64->d_ino;
369 ++ ds->tdp.d_reclen = sizeof (struct dirent)
370 ++ + dp64->d_reclen - offsetof (struct dirent64, d_name);
371 ++ ds->tdp.d_type = dp64->d_type;
372 ++ memcpy (ds->tdp.d_name, dp64->d_name,
373 + dp64->d_reclen - offsetof (struct dirent64, d_name));
374 +
375 + return true;
376 @@ -145,7 +127,19 @@ index c9a04dc160..c078146d7d 100644
377 - bytes = __getdents (dirp->fd, dirp->data, maxread);
378 - if (bytes <= 0)
379 + if (dirp->offset >= dirp->size)
380 -+ {
381 + {
382 +- /* Linux may fail with ENOENT on some file systems if the
383 +- directory inode is marked as dead (deleted). POSIX
384 +- treats this as a regular end-of-directory condition, so
385 +- do not set errno in that case, to indicate success. */
386 +- if (bytes == 0 || errno == ENOENT)
387 +- __set_errno (saved_errno);
388 +- return NULL;
389 +- }
390 +- dirp->size = (size_t) bytes;
391 +-
392 +- /* Reset the offset into the buffer. */
393 +- dirp->offset = 0;
394 + /* We've emptied out our buffer. Refill it. */
395 + ssize_t bytes = __getdents64 (dirp->fd, dirp->data,
396 + dirp->allocation);
397 @@ -169,23 +163,9 @@ index c9a04dc160..c078146d7d 100644
398 + dirp->offset += dp64->d_reclen;
399 +
400 + /* Skip entries which might overflow d_off/d_ino or if the translation
401 -+ buffer can't be resized. */
402 ++ buffer can not be resized. */
403 + if (dirstream_entry (dirp, dp64))
404 - {
405 -- /* Linux may fail with ENOENT on some file systems if the
406 -- directory inode is marked as dead (deleted). POSIX
407 -- treats this as a regular end-of-directory condition, so
408 -- do not set errno in that case, to indicate success. */
409 -- if (bytes == 0 || errno == ENOENT)
410 -- __set_errno (saved_errno);
411 -- return NULL;
412 -+ dirp->filepos = dp64->d_off;
413 -+ return (struct dirent *) dirp->tbuffer;
414 - }
415 -- dirp->size = (size_t) bytes;
416 --
417 -- /* Reset the offset into the buffer. */
418 -- dirp->offset = 0;
419 ++ return &dirp->tdp;
420 }
421 -
422 - dp = (struct dirent *) &dirp->data[dirp->offset];
423 @@ -197,5 +177,5 @@ index c9a04dc160..c078146d7d 100644
424
425 struct dirent *
426 --
427 -2.38.2
428 +2.39.1
429
430
431 diff --git a/9999/0006-linux-Set-internal-DIR-filepos-as-off64_t-BZ-23960-B.patch b/9999/0006-linux-Set-internal-DIR-filepos-as-off64_t-BZ-23960-B.patch
432 index 38acaf8..59e01fc 100644
433 --- a/9999/0006-linux-Set-internal-DIR-filepos-as-off64_t-BZ-23960-B.patch
434 +++ b/9999/0006-linux-Set-internal-DIR-filepos-as-off64_t-BZ-23960-B.patch
435 @@ -1,240 +1,121 @@
436 -From 36f553f67b8268341b7879640637fac5ea806017 Mon Sep 17 00:00:00 2001
437 +From 861793671bd8daeed1f00902d9a9523ddae77462 Mon Sep 17 00:00:00 2001
438 From: Adhemerval Zanella <adhemerval.zanella@××××××.org>
439 -Date: Mon, 13 Apr 2020 18:09:20 -0300
440 -Subject: [PATCH 06/10] linux: Set internal DIR filepos as off64_t [BZ #23960,
441 - BZ #24050]
442 +Date: Fri, 27 Jan 2023 14:28:31 -0300
443 +Subject: [PATCH 6/9] linux: Set internal DIR filepos as off64_t (BZ #23960, BZ
444 + #24050)
445
446 It allows to obtain the expected entry offset on telldir and set
447 it correctly on seekdir on platforms where long int is smaller
448 than off64_t.
449
450 -On such cases telldir will mantain an internal list that maps the
451 -DIR object off64_t offsets to the returned long int (the function
452 -return value). The seekdir will then set the correct offset from
453 -the internal list using the telldir as the list key.
454 +On such cases opendir creates a map entry between the DIR d_off
455 +offset and the returned long int (the telldir return value).
456 +seekdir will then set the correct offset from the internal list
457 +using the telldir as the list key.
458
459 It also removes the overflow check on readdir and the returned value
460 will be truncated by the non-LFS off_t size. As Joseph has noted
461 in BZ #23960 comment #22, d_off is an opaque value and since
462 telldir/seekdir works regardless of the returned dirent d_off value.
463
464 -Finally it removed the requirement to check for overflow values on
465 +Finally it removes the requirement to check for overflow values on
466 telldir (BZ #24050).
467
468 Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc-linux-gnu,
469 and arm-linux-gnueabihf.
470 ---
471 - dirent/Makefile | 2 +-
472 - dirent/tst-seekdir2.c | 158 ++++++++++++++++++++++++++++
473 - sysdeps/unix/sysv/linux/closedir.c | 4 +
474 - sysdeps/unix/sysv/linux/dirstream.h | 6 +-
475 - sysdeps/unix/sysv/linux/opendir.c | 3 +
476 - sysdeps/unix/sysv/linux/readdir.c | 1 +
477 - sysdeps/unix/sysv/linux/rewinddir.c | 5 +
478 - sysdeps/unix/sysv/linux/seekdir.c | 36 ++++++-
479 - sysdeps/unix/sysv/linux/telldir.c | 47 ++++++++-
480 - sysdeps/unix/sysv/linux/telldir.h | 64 +++++++++++
481 - 10 files changed, 317 insertions(+), 9 deletions(-)
482 - create mode 100644 dirent/tst-seekdir2.c
483 + dirent/tst-seekdir.c | 8 ++
484 + sysdeps/unix/sysv/linux/Makefile | 1 +
485 + sysdeps/unix/sysv/linux/alpha/bits/dirent.h | 3 +
486 + sysdeps/unix/sysv/linux/bits/dirent.h | 4 +
487 + sysdeps/unix/sysv/linux/closedir.c | 4 +
488 + sysdeps/unix/sysv/linux/dirstream.h | 6 +-
489 + sysdeps/unix/sysv/linux/opendir.c | 3 +
490 + sysdeps/unix/sysv/linux/readdir.c | 11 +-
491 + sysdeps/unix/sysv/linux/rewinddir.c | 5 +
492 + sysdeps/unix/sysv/linux/seekdir.c | 35 ++++-
493 + sysdeps/unix/sysv/linux/telldir.c | 35 +++++
494 + sysdeps/unix/sysv/linux/telldir.h | 65 +++++++++
495 + sysdeps/unix/sysv/linux/tst-opendir-nolfs.c | 146 ++++++++++++++++++++
496 + 13 files changed, 319 insertions(+), 7 deletions(-)
497 create mode 100644 sysdeps/unix/sysv/linux/telldir.h
498 + create mode 100644 sysdeps/unix/sysv/linux/tst-opendir-nolfs.c
499
500 -diff --git a/dirent/Makefile b/dirent/Makefile
501 -index cfa61826ed..9a9d91b8a5 100644
502 ---- a/dirent/Makefile
503 -+++ b/dirent/Makefile
504 -@@ -31,7 +31,7 @@ routines := opendir closedir readdir readdir_r rewinddir \
505 - scandir-cancel scandir-tail scandir64-tail
506 -
507 - tests := list tst-seekdir opendir-tst1 bug-readdir1 tst-fdopendir \
508 -- tst-fdopendir2 tst-scandir tst-scandir64
509 -+ tst-fdopendir2 tst-scandir tst-scandir64 tst-seekdir2
510 -
511 - CFLAGS-scandir.c += $(uses-callbacks)
512 - CFLAGS-scandir64.c += $(uses-callbacks)
513 -diff --git a/dirent/tst-seekdir2.c b/dirent/tst-seekdir2.c
514 -new file mode 100644
515 -index 0000000000..3e01b361e5
516 ---- /dev/null
517 -+++ b/dirent/tst-seekdir2.c
518 -@@ -0,0 +1,158 @@
519 -+/* Check multiple telldir and seekdir.
520 -+ Copyright (C) 2020 Free Software Foundation, Inc.
521 -+ This file is part of the GNU C Library.
522 -+
523 -+ The GNU C Library is free software; you can redistribute it and/or
524 -+ modify it under the terms of the GNU Lesser General Public
525 -+ License as published by the Free Software Foundation; either
526 -+ version 2.1 of the License, or (at your option) any later version.
527 -+
528 -+ The GNU C Library is distributed in the hope that it will be useful,
529 -+ but WITHOUT ANY WARRANTY; without even the implied warranty of
530 -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
531 -+ Lesser General Public License for more details.
532 -+
533 -+ You should have received a copy of the GNU Lesser General Public
534 -+ License along with the GNU C Library; if not, see
535 -+ <https://www.gnu.org/licenses/>. */
536 -+
537 -+#include <dirent.h>
538 -+#include <stdlib.h>
539 -+#include <unistd.h>
540 -+#include <stdio.h>
541 -+#include <string.h>
542 -+
543 -+#include <support/temp_file.h>
544 -+#include <support/support.h>
545 -+#include <support/check.h>
546 -+
547 -+/* Some filesystems returns a arbitrary value for d_off direnty entry (ext4
548 -+ for instance, where the value is an internal hash key). The idea of
549 -+ create a large number of file is to try trigger a overflow d_off value
550 -+ in a entry to check if telldir/seekdir does work corretly in such
551 -+ case. */
552 -+static const char *dirname;
553 -+static const size_t nfiles = 10240;
554 -+
555 -+static void
556 -+do_prepare (int argc, char *argv[])
557 -+{
558 -+ dirname = support_create_temp_directory ("tst-seekdir2-");
559 -+
560 -+ for (size_t i = 0; i < nfiles; i++)
561 +diff --git a/dirent/tst-seekdir.c b/dirent/tst-seekdir.c
562 +index dcdd699b09..187eda7584 100644
563 +--- a/dirent/tst-seekdir.c
564 ++++ b/dirent/tst-seekdir.c
565 +@@ -41,6 +41,14 @@ do_test (void)
566 + if (i == 400)
567 + break;
568 + }
569 ++ if (i < 3)
570 + {
571 -+ int fd = create_temp_file_in_dir ("tempfile.", dirname, NULL);
572 -+ TEST_VERIFY_EXIT (fd > 0);
573 -+ close (fd);
574 -+ }
575 -+}
576 -+#define PREPARE do_prepare
577 -+
578 -+/* Check for old non Large File Support (LFS). */
579 -+static int
580 -+do_test_not_lfs (void)
581 -+{
582 -+ DIR *dirp = opendir (dirname);
583 -+ TEST_VERIFY_EXIT (dirp != NULL);
584 -+
585 -+ size_t dirp_count = 0;
586 -+ for (struct dirent *dp = readdir (dirp);
587 -+ dp != NULL;
588 -+ dp = readdir (dirp))
589 -+ dirp_count++;
590 -+
591 -+ /* The 2 extra files are '.' and '..'. */
592 -+ TEST_COMPARE (dirp_count, nfiles + 2);
593 -+
594 -+ rewinddir (dirp);
595 -+
596 -+ long *tdirp = xmalloc (dirp_count * sizeof (long));
597 -+ struct dirent **ddirp = xmalloc (dirp_count * sizeof (struct dirent *));
598 -+
599 -+ size_t i = 0;
600 -+ do
601 -+ {
602 -+ tdirp[i] = telldir (dirp);
603 -+ struct dirent *dp = readdir (dirp);
604 -+ TEST_VERIFY_EXIT (dp != NULL);
605 -+ ddirp[i] = xmalloc (dp->d_reclen);
606 -+ memcpy (ddirp[i], dp, dp->d_reclen);
607 -+ } while (++i < dirp_count);
608 -+
609 -+ for (i = 0; i < dirp_count - 1; i++)
610 -+ {
611 -+ seekdir (dirp, tdirp[i]);
612 -+ struct dirent *dp = readdir (dirp);
613 -+ TEST_COMPARE (strcmp (dp->d_name, ddirp[i]->d_name), 0);
614 -+ TEST_COMPARE (dp->d_ino, ddirp[i]->d_ino);
615 -+ TEST_COMPARE (dp->d_off, ddirp[i]->d_off);
616 ++ /* Non-lfs opendir skips entries that can not be represented (for
617 ++ instance if d_off is not an offset but rather an internal filesystem
618 ++ representation. For this case there is no point in continue the
619 ++ testcase. */
620 ++ return 77;
621 + }
622 +
623 + printf ("going back past 4-th entry...\n");
624 +
625 +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
626 +index f8bd12d991..09adb99b86 100644
627 +--- a/sysdeps/unix/sysv/linux/Makefile
628 ++++ b/sysdeps/unix/sysv/linux/Makefile
629 +@@ -464,6 +464,7 @@ ifeq ($(subdir),dirent)
630 + sysdep_routines += getdirentries getdirentries64
631 + tests += \
632 + tst-getdents64 \
633 ++ tst-opendir-nolfs \
634 + tst-readdir64-compat \
635 + # tests
636 + endif # $(subdir) == dirent
637 +diff --git a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
638 +index c8a0cfe93f..586d75586a 100644
639 +--- a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
640 ++++ b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
641 +@@ -54,4 +54,7 @@ struct dirent64
642 + /* Inform libc code that these two types are effectively identical. */
643 + #define _DIRENT_MATCHES_DIRENT64 1
644 +
645 ++/* alpha 'long int' is enough to handle off64_t. */
646 ++#define _DIRENT_OFFSET_TRANSLATION 0
647 ++
648 + #endif /* bits/dirent.h */
649 +diff --git a/sysdeps/unix/sysv/linux/bits/dirent.h b/sysdeps/unix/sysv/linux/bits/dirent.h
650 +index ab34d986ff..bb02dcb70a 100644
651 +--- a/sysdeps/unix/sysv/linux/bits/dirent.h
652 ++++ b/sysdeps/unix/sysv/linux/bits/dirent.h
653 +@@ -57,3 +57,7 @@ struct dirent64
654 + #else
655 + # define _DIRENT_MATCHES_DIRENT64 0
656 + #endif
657 +
658 -+ closedir (dirp);
659 -+ free (tdirp);
660 -+ for (i = 0; i < dirp_count; i++)
661 -+ free (ddirp[i]);
662 -+ free (ddirp);
663 -+
664 -+ return 0;
665 -+}
666 -+
667 -+/* Same as before but with LFS support. */
668 -+static int
669 -+do_test_lfs (void)
670 -+{
671 -+ DIR *dirp = opendir (dirname);
672 -+ TEST_VERIFY_EXIT (dirp != NULL);
673 -+
674 -+ size_t dirp_count = 0;
675 -+ for (struct dirent64 * dp = readdir64 (dirp);
676 -+ dp != NULL;
677 -+ dp = readdir64 (dirp))
678 -+ dirp_count++;
679 -+
680 -+ /* The 2 extra files are '.' and '..'. */
681 -+ TEST_COMPARE (dirp_count, nfiles + 2);
682 -+
683 -+ rewinddir (dirp);
684 -+
685 -+ long *tdirp = xmalloc (dirp_count * sizeof (long));
686 -+ struct dirent64 **ddirp = xmalloc (dirp_count * sizeof (struct dirent64 *));
687 -+
688 -+ size_t i = 0;
689 -+ do
690 -+ {
691 -+ tdirp[i] = telldir (dirp);
692 -+ struct dirent64 *dp = readdir64 (dirp);
693 -+ TEST_VERIFY_EXIT (dp != NULL);
694 -+ ddirp[i] = xmalloc (dp->d_reclen);
695 -+ memcpy (ddirp[i], dp, dp->d_reclen);
696 -+ } while (++i < dirp_count);
697 -+
698 -+ for (i = 0; i < dirp_count - 1; i++)
699 -+ {
700 -+ seekdir (dirp, tdirp[i]);
701 -+ struct dirent64 *dp = readdir64 (dirp);
702 -+ TEST_COMPARE (strcmp (dp->d_name, ddirp[i]->d_name), 0);
703 -+ TEST_COMPARE (dp->d_ino, ddirp[i]->d_ino);
704 -+ TEST_COMPARE (dp->d_off, ddirp[i]->d_off);
705 -+ }
706 -+
707 -+ closedir (dirp);
708 -+ free (tdirp);
709 -+ for (i = 0; i < dirp_count; i++)
710 -+ free (ddirp[i]);
711 -+ free (ddirp);
712 -+
713 -+ return 0;
714 -+}
715 -+
716 -+static int
717 -+do_test (void)
718 -+{
719 -+ do_test_not_lfs ();
720 -+ do_test_lfs ();
721 -+
722 -+ return 0;
723 -+}
724 -+
725 -+#include <support/test-driver.c>
726 ++/* The telldir function returns long int, which may not be large enough to
727 ++ store off64_t values. In this case, translation is required. */
728 ++#define _DIRENT_OFFSET_TRANSLATION (LONG_WIDTH < 64)
729 diff --git a/sysdeps/unix/sysv/linux/closedir.c b/sysdeps/unix/sysv/linux/closedir.c
730 -index d876d49d78..8e5669963c 100644
731 +index f1c2608642..9585a6ca3a 100644
732 --- a/sysdeps/unix/sysv/linux/closedir.c
733 +++ b/sysdeps/unix/sysv/linux/closedir.c
734 -@@ -43,6 +43,10 @@ __closedir (DIR *dirp)
735 -
736 - fd = dirp->fd;
737 +@@ -47,6 +47,10 @@ __closedir (DIR *dirp)
738 + __libc_lock_fini (dirp->lock);
739 + #endif
740
741 -+#ifndef __LP64__
742 ++#if _DIRENT_OFFSET_TRANSLATION
743 + dirstream_loc_clear (&dirp->locs);
744 +#endif
745 +
746 - #if IS_IN (libc)
747 - __libc_lock_fini (dirp->lock);
748 - #endif
749 + free ((void *) dirp);
750 +
751 + return __close_nocancel (fd);
752 diff --git a/sysdeps/unix/sysv/linux/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h
753 -index 064273cc31..a284292cb2 100644
754 +index adcf8234f1..8f58a1c3a6 100644
755 --- a/sysdeps/unix/sysv/linux/dirstream.h
756 +++ b/sysdeps/unix/sysv/linux/dirstream.h
757 -@@ -21,6 +21,7 @@
758 +@@ -22,6 +22,7 @@
759 #include <sys/types.h>
760
761 #include <libc-lock.h>
762 @@ -242,7 +123,7 @@ index 064273cc31..a284292cb2 100644
763
764 /* Directory stream type.
765
766 -@@ -37,7 +38,7 @@ struct __dirstream
767 +@@ -38,13 +39,16 @@ struct __dirstream
768 size_t size; /* Total valid data in the block. */
769 size_t offset; /* Current offset into the block. */
770
771 @@ -251,44 +132,60 @@ index 064273cc31..a284292cb2 100644
772
773 int errcode; /* Delayed error code. */
774
775 -@@ -45,6 +46,9 @@ struct __dirstream
776 - char *tbuffer; /* Translation buffer for non-LFS calls. */
777 - size_t tbuffer_size; /* Size of translation buffer. */
778 + #if !defined __OFF_T_MATCHES_OFF64_T || !defined __INO_T_MATCHES_INO64_T
779 + struct dirent tdp;
780 #endif
781 -+#ifndef __LP64__
782 ++#if _DIRENT_OFFSET_TRANSLATION
783 + struct dirstream_loc_t locs; /* off64_t to long int map for telldir. */
784 +#endif
785
786 /* Directory block. We must make sure that this block starts
787 at an address that is aligned adequately enough to store
788 diff --git a/sysdeps/unix/sysv/linux/opendir.c b/sysdeps/unix/sysv/linux/opendir.c
789 -index bfd2f382a6..9a0b7ab4c4 100644
790 +index 4336196a4d..3e2caabb9d 100644
791 --- a/sysdeps/unix/sysv/linux/opendir.c
792 +++ b/sysdeps/unix/sysv/linux/opendir.c
793 -@@ -150,6 +150,9 @@ __alloc_dir (int fd, bool close_fd, int flags,
794 +@@ -129,6 +129,9 @@ __alloc_dir (int fd, bool close_fd, int flags,
795 dirp->offset = 0;
796 dirp->filepos = 0;
797 dirp->errcode = 0;
798 -+#ifndef __LP64__
799 ++#if _DIRENT_OFFSET_TRANSLATION
800 + dirstream_loc_init (&dirp->locs);
801 +#endif
802
803 return dirp;
804 }
805 diff --git a/sysdeps/unix/sysv/linux/readdir.c b/sysdeps/unix/sysv/linux/readdir.c
806 -index c078146d7d..f377e5f268 100644
807 +index cd0ccaf33a..7a7f484c36 100644
808 --- a/sysdeps/unix/sysv/linux/readdir.c
809 +++ b/sysdeps/unix/sysv/linux/readdir.c
810 -@@ -17,6 +17,7 @@
811 - <https://www.gnu.org/licenses/>. */
812 +@@ -36,6 +36,15 @@ dirstream_entry (struct __dirstream *ds, const struct dirent64 *dp64)
813 + if (dp64->d_reclen - offsetof (struct dirent64, d_name) > NAME_MAX)
814 + return false;
815
816 - #include <dirent.h>
817 -+#include <unistd.h>
818 ++ /* telldir can not return an error, so preallocate the map if the entry can
819 ++ not be packed directly. */
820 ++ if (telldir_need_dirstream (dp64->d_off))
821 ++ {
822 ++ dirstream_loc_add (&ds->locs, dp64->d_off);
823 ++ if (dirstream_loc_has_failed (&ds->locs))
824 ++ return false;
825 ++ }
826 ++
827 + ds->filepos = dp64->d_off;
828
829 - #if !_DIRENT_MATCHES_DIRENT64
830 - #include <dirstream.h>
831 + ds->tdp.d_off = dp64->d_off;
832 +@@ -76,7 +85,7 @@ __readdir_unlocked (DIR *dirp)
833 +
834 + /* Reset the offset into the buffer. */
835 + dirp->offset = 0;
836 +- }
837 ++ }
838 +
839 + struct dirent64 *dp64 = (struct dirent64 *) &dirp->data[dirp->offset];
840 + dirp->offset += dp64->d_reclen;
841 diff --git a/sysdeps/unix/sysv/linux/rewinddir.c b/sysdeps/unix/sysv/linux/rewinddir.c
842 -index b1e8259703..0194d29e38 100644
843 +index c0fb7aa765..1b158a584f 100644
844 --- a/sysdeps/unix/sysv/linux/rewinddir.c
845 +++ b/sysdeps/unix/sysv/linux/rewinddir.c
846 @@ -33,6 +33,11 @@ __rewinddir (DIR *dirp)
847 @@ -304,10 +201,10 @@ index b1e8259703..0194d29e38 100644
848 __libc_lock_unlock (dirp->lock);
849 #endif
850 diff --git a/sysdeps/unix/sysv/linux/seekdir.c b/sysdeps/unix/sysv/linux/seekdir.c
851 -index f4e1a9f8e0..0c3e58a2ed 100644
852 +index 939ccc4447..30cce691a4 100644
853 --- a/sysdeps/unix/sysv/linux/seekdir.c
854 +++ b/sysdeps/unix/sysv/linux/seekdir.c
855 -@@ -22,14 +22,40 @@
856 +@@ -22,14 +22,39 @@
857 #include <dirstream.h>
858
859 /* Seek to position POS in DIRP. */
860 @@ -323,11 +220,8 @@ index f4e1a9f8e0..0c3e58a2ed 100644
861 - dirp->offset = 0;
862 - dirp->filepos = pos;
863 +
864 -+#ifndef __LP64__
865 -+ union dirstream_packed dsp;
866 -+
867 -+ dsp.l = pos;
868 -+
869 ++#if _DIRENT_OFFSET_TRANSLATION
870 ++ union dirstream_packed dsp = { .l = pos };
871 + if (dsp.p.is_packed == 1)
872 + filepos = dsp.p.info;
873 + else
874 @@ -335,9 +229,11 @@ index f4e1a9f8e0..0c3e58a2ed 100644
875 + size_t index = dsp.p.info;
876 +
877 + if (index >= dirstream_loc_size (&dirp->locs))
878 -+ return;
879 -+ struct dirstream_loc *loc = dirstream_loc_at (&dirp->locs, index);
880 -+ filepos = loc->filepos;
881 ++ {
882 ++ __libc_lock_unlock (dirp->lock);
883 ++ return;
884 ++ }
885 ++ filepos = *dirstream_loc_at (&dirp->locs, index);
886 + }
887 +#else
888 + filepos = pos;
889 @@ -354,10 +250,14 @@ index f4e1a9f8e0..0c3e58a2ed 100644
890 __libc_lock_unlock (dirp->lock);
891 }
892 diff --git a/sysdeps/unix/sysv/linux/telldir.c b/sysdeps/unix/sysv/linux/telldir.c
893 -index b60b231e48..874905489f 100644
894 +index 1e5c129e9f..c3ef14f3da 100644
895 --- a/sysdeps/unix/sysv/linux/telldir.c
896 +++ b/sysdeps/unix/sysv/linux/telldir.c
897 -@@ -18,16 +18,59 @@
898 +@@ -15,9 +15,11 @@
899 + License along with the GNU C Library; if not, see
900 + <https://www.gnu.org/licenses/>. */
901 +
902 ++#include <assert.h>
903 #include <dirent.h>
904
905 #include <dirstream.h>
906 @@ -365,68 +265,55 @@ index b60b231e48..874905489f 100644
907
908 /* Return the current position of DIRP. */
909 long int
910 - telldir (DIR *dirp)
911 - {
912 -- long int ret;
913 -+#ifndef __LP64__
914 -+ /* If the directory position fits in the packet structure returns it.
915 +@@ -26,7 +28,40 @@ telldir (DIR *dirp)
916 + long int ret;
917 +
918 + __libc_lock_lock (dirp->lock);
919 ++
920 ++#if _DIRENT_OFFSET_TRANSLATION
921 ++ /* If the directory position fits in the packet structure, returns it.
922 + Otherwise, check if the position is already been recorded in the
923 + dynamic array. If not, add the new record. */
924 +
925 + union dirstream_packed dsp;
926 -+ size_t i;
927 -
928 - __libc_lock_lock (dirp->lock);
929 -- ret = dirp->filepos;
930 +
931 -+ if (dirp->filepos < (1U << 31))
932 ++ if (!telldir_need_dirstream (dirp->filepos))
933 + {
934 + dsp.p.is_packed = 1;
935 + dsp.p.info = dirp->filepos;
936 -+ goto out;
937 + }
938 -+
939 -+ dsp.l = -1;
940 -+
941 -+ for (i = 0; i < dirstream_loc_size (&dirp->locs); i++)
942 -+ {
943 -+ struct dirstream_loc *loc = dirstream_loc_at (&dirp->locs, i);
944 -+ if (loc->filepos == dirp->filepos)
945 -+ break;
946 -+ }
947 -+ if (i == dirstream_loc_size (&dirp->locs))
948 ++ else
949 + {
950 -+ dirstream_loc_add (&dirp->locs,
951 -+ (struct dirstream_loc) { dirp->filepos });
952 -+ if (dirstream_loc_has_failed (&dirp->locs))
953 -+ goto out;
954 ++ dsp.l = -1;
955 ++
956 ++ size_t i;
957 ++ for (i = 0; i < dirstream_loc_size (&dirp->locs); i++)
958 ++ if (*dirstream_loc_at (&dirp->locs, i) == dirp->filepos)
959 ++ break;
960 ++ /* It should be pre-allocated on readdir. */
961 ++ assert (i != dirstream_loc_size (&dirp->locs));
962 ++
963 ++ dsp.p.is_packed = 0;
964 ++ /* This assignment might overflow, however most likely ENOME would
965 ++ happen long before. */
966 ++ dsp.p.info = i;
967 + }
968 +
969 -+ dsp.p.is_packed = 0;
970 -+ /* This assignment might overflow, however most likely ENOMEM would happen
971 -+ long before. */
972 -+ dsp.p.info = i;
973 -+
974 -+out:
975 ++ ret = dsp.l;
976 ++#else
977 + ret = dirp->filepos;
978 ++#endif
979 __libc_lock_unlock (dirp->lock);
980
981 -+ return dsp.l;
982 -+#else
983 -+ long int ret;
984 -+ __libc_lock_lock (dirp->lock);
985 -+ ret = dirp->filepos;
986 -+ __libc_lock_unlock (dirp->lock);
987 return ret;
988 -+#endif
989 - }
990 diff --git a/sysdeps/unix/sysv/linux/telldir.h b/sysdeps/unix/sysv/linux/telldir.h
991 new file mode 100644
992 -index 0000000000..7c45886341
993 +index 0000000000..758bcb0eb3
994 --- /dev/null
995 +++ b/sysdeps/unix/sysv/linux/telldir.h
996 -@@ -0,0 +1,64 @@
997 +@@ -0,0 +1,65 @@
998 +/* Linux internal telldir definitions.
999 -+ Copyright (C) 2020 Free Software Foundation, Inc.
1000 ++ Copyright (C) 2023 Free Software Foundation, Inc.
1001 + This file is part of the GNU C Library.
1002 +
1003 + The GNU C Library is free software; you can redistribute it and/or
1004 @@ -446,9 +333,8 @@ index 0000000000..7c45886341
1005 +#ifndef _TELLDIR_H
1006 +#define _TELLDIR_H 1
1007 +
1008 -+#ifndef __LP64__
1009 -+
1010 -+/* On platforms where long int is smaller than off64_t this is how the
1011 ++#if _DIRENT_OFFSET_TRANSLATION
1012 ++/* On platforms where 'long int' is smaller than 'off64_t' this is how the
1013 + returned value is encoded and returned by 'telldir'. If the directory
1014 + offset can be enconded in 31 bits it is returned in the 'info' member
1015 + with 'is_packed' set to 1.
1016 @@ -461,34 +347,188 @@ index 0000000000..7c45886341
1017 + long int l;
1018 + struct
1019 + {
1020 -+ unsigned long is_packed:1;
1021 -+ unsigned long info:31;
1022 ++ unsigned long int is_packed:1;
1023 ++ unsigned long int info:31;
1024 + } p;
1025 +};
1026 +
1027 +_Static_assert (sizeof (long int) == sizeof (union dirstream_packed),
1028 + "sizeof (long int) != sizeof (union dirstream_packed)");
1029 +
1030 -+/* telldir will mantain a list of offsets that describe the obtained diretory
1031 ++/* telldir maintains a list of offsets that describe the obtained diretory
1032 + position if it can fit this information in the returned 'dirstream_packed'
1033 + struct. */
1034 +
1035 -+struct dirstream_loc
1036 -+{
1037 -+ off64_t filepos;
1038 -+};
1039 -+
1040 +# define DYNARRAY_STRUCT dirstream_loc_t
1041 -+# define DYNARRAY_ELEMENT struct dirstream_loc
1042 ++# define DYNARRAY_ELEMENT off64_t
1043 +# define DYNARRAY_PREFIX dirstream_loc_
1044 +# include <malloc/dynarray-skeleton.c>
1045 ++
1046 ++static __always_inline bool
1047 ++telldir_need_dirstream (__off64_t d_off)
1048 ++{
1049 ++ return d_off >= 1UL << 31;
1050 ++}
1051 +#else
1052 +
1053 +_Static_assert (sizeof (long int) == sizeof (off64_t),
1054 + "sizeof (long int) != sizeof (off64_t)");
1055 ++
1056 +#endif /* __LP64__ */
1057 +
1058 +#endif /* _TELLDIR_H */
1059 +diff --git a/sysdeps/unix/sysv/linux/tst-opendir-nolfs.c b/sysdeps/unix/sysv/linux/tst-opendir-nolfs.c
1060 +new file mode 100644
1061 +index 0000000000..52e18171a7
1062 +--- /dev/null
1063 ++++ b/sysdeps/unix/sysv/linux/tst-opendir-nolfs.c
1064 +@@ -0,0 +1,146 @@
1065 ++/* Check multiple telldir and seekdir.
1066 ++ Copyright (C) 2023 Free Software Foundation, Inc.
1067 ++ This file is part of the GNU C Library.
1068 ++
1069 ++ The GNU C Library is free software; you can redistribute it and/or
1070 ++ modify it under the terms of the GNU Lesser General Public
1071 ++ License as published by the Free Software Foundation; either
1072 ++ version 2.1 of the License, or (at your option) any later version.
1073 ++
1074 ++ The GNU C Library is distributed in the hope that it will be useful,
1075 ++ but WITHOUT ANY WARRANTY; without even the implied warranty of
1076 ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1077 ++ Lesser General Public License for more details.
1078 ++
1079 ++ You should have received a copy of the GNU Lesser General Public
1080 ++ License along with the GNU C Library; if not, see
1081 ++ <https://www.gnu.org/licenses/>. */
1082 ++
1083 ++#include <dirent.h>
1084 ++#include <fcntl.h>
1085 ++#include <stdio.h>
1086 ++#include <stdlib.h>
1087 ++#include <string.h>
1088 ++#include <unistd.h>
1089 ++
1090 ++#include <support/check.h>
1091 ++#include <support/support.h>
1092 ++#include <support/temp_file.h>
1093 ++#include <support/xunistd.h>
1094 ++
1095 ++/* Some filesystems returns an arbitrary value for d_off direnty entry (ext4
1096 ++ for instance, where the value is an internal hash key). The idea of create
1097 ++ a large number of file is to try trigger a overflow d_off value in a entry
1098 ++ to check if telldir/seekdir does work corretly in such case. */
1099 ++static const char *dirname;
1100 ++/* The 2 extra files are '.' and '..'. */
1101 ++static const size_t nfiles = (1<<14) + 2;
1102 ++
1103 ++static inline bool
1104 ++in_ino_t_range (ino64_t v)
1105 ++{
1106 ++ ino_t s = v;
1107 ++ return s == v;
1108 ++}
1109 ++
1110 ++static inline bool
1111 ++in_off_t_range (off64_t v)
1112 ++{
1113 ++ off_t s = v;
1114 ++ return s == v;
1115 ++}
1116 ++
1117 ++static void
1118 ++do_prepare (int argc, char *argv[])
1119 ++{
1120 ++ dirname = support_create_temp_directory ("tst-opendir-nolfs-");
1121 ++
1122 ++ for (size_t i = 0; i < nfiles - 2; i++)
1123 ++ {
1124 ++ int fd = create_temp_file_in_dir ("tempfile.", dirname, NULL);
1125 ++ TEST_VERIFY_EXIT (fd > 0);
1126 ++ close (fd);
1127 ++ }
1128 ++}
1129 ++#define PREPARE do_prepare
1130 ++
1131 ++static int
1132 ++do_test (void)
1133 ++{
1134 ++ DIR *dirp = opendir (dirname);
1135 ++ TEST_VERIFY_EXIT (dirp != NULL);
1136 ++
1137 ++ long int *tdirp = xmalloc (nfiles * sizeof (long int));
1138 ++ struct dirent **ddirp = xmalloc (nfiles * sizeof (struct dirent *));
1139 ++
1140 ++ /* For non-LFS, the entry is skipped if it can not be converted. */
1141 ++ int count = 0;
1142 ++ for (; count < nfiles; count++)
1143 ++ {
1144 ++ tdirp[count] = telldir (dirp);
1145 ++ struct dirent *dp = readdir (dirp);
1146 ++ if (dp == NULL)
1147 ++ break;
1148 ++ ddirp[count] = xmalloc (dp->d_reclen);
1149 ++ memcpy (ddirp[count], dp, dp->d_reclen);
1150 ++ }
1151 ++
1152 ++ closedir (dirp);
1153 ++
1154 ++ /* Check against the getdents64 syscall. */
1155 ++ int fd = xopen (dirname, O_RDONLY | O_DIRECTORY, 0);
1156 ++ int i = 0;
1157 ++ while (true)
1158 ++ {
1159 ++ struct
1160 ++ {
1161 ++ char buffer[1024];
1162 ++ struct dirent64 pad;
1163 ++ } data;
1164 ++
1165 ++ ssize_t ret = getdents64 (fd, &data.buffer, sizeof (data.buffer));
1166 ++ if (ret < 0)
1167 ++ FAIL_EXIT1 ("getdents64: %m");
1168 ++ if (ret == 0)
1169 ++ break;
1170 ++
1171 ++ char *current = data.buffer;
1172 ++ char *end = data.buffer + ret;
1173 ++ while (current != end)
1174 ++ {
1175 ++ struct dirent64 entry;
1176 ++ memcpy (&entry, current, sizeof (entry));
1177 ++ /* Truncate overlong strings. */
1178 ++ entry.d_name[sizeof (entry.d_name) - 1] = '\0';
1179 ++ TEST_VERIFY (strlen (entry.d_name) < sizeof (entry.d_name) - 1);
1180 ++
1181 ++ if (in_ino_t_range (entry.d_ino) && in_off_t_range (entry.d_off))
1182 ++ {
1183 ++ TEST_COMPARE_STRING (entry.d_name, ddirp[i]->d_name);
1184 ++ TEST_COMPARE (entry.d_ino, ddirp[i]->d_ino);
1185 ++ TEST_COMPARE (entry.d_off, ddirp[i]->d_off);
1186 ++ TEST_COMPARE (entry.d_type, ddirp[i]->d_type);
1187 ++
1188 ++ /* Offset zero is reserved for the first entry. */
1189 ++ TEST_VERIFY (entry.d_off != 0);
1190 ++
1191 ++ TEST_VERIFY_EXIT (entry.d_reclen <= end - current);
1192 ++ i++;
1193 ++ }
1194 ++
1195 ++ current += entry.d_reclen;
1196 ++ }
1197 ++ }
1198 ++
1199 ++ /* direntries_read has been called more than once. */
1200 ++ TEST_COMPARE (count, i);
1201 ++
1202 ++ free (tdirp);
1203 ++ for (int i = 0; i < count; i++)
1204 ++ free (ddirp[i]);
1205 ++ free (ddirp);
1206 ++
1207 ++ return 0;
1208 ++}
1209 ++
1210 ++#include <support/test-driver.c>
1211 --
1212 -2.38.2
1213 +2.39.1
1214
1215
1216 diff --git a/9999/0007-linux-Add-__readdir64_unlocked.patch b/9999/0007-linux-Add-__readdir64_unlocked.patch
1217 index 631550c..18dcda4 100644
1218 --- a/9999/0007-linux-Add-__readdir64_unlocked.patch
1219 +++ b/9999/0007-linux-Add-__readdir64_unlocked.patch
1220 @@ -1,7 +1,7 @@
1221 -From 4cca67d0d2d615918e05db864c236e33c0fda8f3 Mon Sep 17 00:00:00 2001
1222 +From f697eec9ff1939e46d7730aa5cc0f696f41d8bd7 Mon Sep 17 00:00:00 2001
1223 From: Adhemerval Zanella <adhemerval.zanella@××××××.org>
1224 -Date: Mon, 13 Apr 2020 08:35:40 -0300
1225 -Subject: [PATCH 07/10] linux: Add __readdir64_unlocked
1226 +Date: Fri, 27 Jan 2023 14:28:32 -0300
1227 +Subject: [PATCH 7/9] linux: Add __readdir64_unlocked
1228
1229 And use it on readdir_r implementation.
1230
1231 @@ -13,7 +13,7 @@ Checked on i686-linux-gnu.
1232 3 files changed, 33 insertions(+), 68 deletions(-)
1233
1234 diff --git a/include/dirent.h b/include/dirent.h
1235 -index d7567f5e86..0c6715d0e4 100644
1236 +index 17827176ba..f391476298 100644
1237 --- a/include/dirent.h
1238 +++ b/include/dirent.h
1239 @@ -21,6 +21,7 @@ extern DIR *__fdopendir (int __fd) attribute_hidden;
1240 @@ -25,7 +25,7 @@ index d7567f5e86..0c6715d0e4 100644
1241 libc_hidden_proto (__readdir64)
1242 extern int __readdir_r (DIR *__dirp, struct dirent *__entry,
1243 diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
1244 -index 7952da5c27..9d82054182 100644
1245 +index db1c6214d8..2327511736 100644
1246 --- a/sysdeps/unix/sysv/linux/readdir64.c
1247 +++ b/sysdeps/unix/sysv/linux/readdir64.c
1248 @@ -28,15 +28,11 @@
1249 @@ -67,7 +67,7 @@ index 7952da5c27..9d82054182 100644
1250 __libc_lock_unlock (dirp->lock);
1251 #endif
1252 diff --git a/sysdeps/unix/sysv/linux/readdir64_r.c b/sysdeps/unix/sysv/linux/readdir64_r.c
1253 -index afd7f9af0f..32962a176a 100644
1254 +index 285dc99509..5ae099bde7 100644
1255 --- a/sysdeps/unix/sysv/linux/readdir64_r.c
1256 +++ b/sysdeps/unix/sysv/linux/readdir64_r.c
1257 @@ -32,89 +32,43 @@ __readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
1258 @@ -178,5 +178,5 @@ index afd7f9af0f..32962a176a 100644
1259
1260
1261 --
1262 -2.38.2
1263 +2.39.1
1264
1265
1266 diff --git a/9999/0008-linux-Add-__old_readdir64_unlocked.patch b/9999/0008-linux-Add-__old_readdir64_unlocked.patch
1267 index 3cd2923..a1d289a 100644
1268 --- a/9999/0008-linux-Add-__old_readdir64_unlocked.patch
1269 +++ b/9999/0008-linux-Add-__old_readdir64_unlocked.patch
1270 @@ -1,7 +1,7 @@
1271 -From cd6d96ae0a09c1bff40f19d54e2910d7d4e74864 Mon Sep 17 00:00:00 2001
1272 +From 5af443d8a53475680fdc51ff1c496b13a9e9e6d0 Mon Sep 17 00:00:00 2001
1273 From: Adhemerval Zanella <adhemerval.zanella@××××××.org>
1274 -Date: Tue, 14 Apr 2020 11:14:22 -0300
1275 -Subject: [PATCH 08/10] linux: Add __old_readdir64_unlocked
1276 +Date: Fri, 27 Jan 2023 14:28:33 -0300
1277 +Subject: [PATCH 8/9] linux: Add __old_readdir64_unlocked
1278
1279 And use it __old_readdir64_r.
1280
1281 @@ -13,7 +13,7 @@ Checked on i686-linux-gnu.
1282 3 files changed, 35 insertions(+), 70 deletions(-)
1283
1284 diff --git a/sysdeps/unix/sysv/linux/olddirent.h b/sysdeps/unix/sysv/linux/olddirent.h
1285 -index 9a22609177..00c84b9521 100644
1286 +index 9789ffae07..cde95e192e 100644
1287 --- a/sysdeps/unix/sysv/linux/olddirent.h
1288 +++ b/sysdeps/unix/sysv/linux/olddirent.h
1289 @@ -32,6 +32,8 @@ struct __old_dirent64
1290 @@ -26,7 +26,7 @@ index 9a22609177..00c84b9521 100644
1291 struct __old_dirent64 **__result);
1292 extern __ssize_t __old_getdents64 (int __fd, char *__buf, size_t __nbytes)
1293 diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
1294 -index 9d82054182..bbe247f95d 100644
1295 +index 2327511736..b901071aa7 100644
1296 --- a/sysdeps/unix/sysv/linux/readdir64.c
1297 +++ b/sysdeps/unix/sysv/linux/readdir64.c
1298 @@ -104,15 +104,11 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
1299 @@ -79,7 +79,7 @@ index 9d82054182..bbe247f95d 100644
1300 __libc_lock_unlock (dirp->lock);
1301 #endif
1302 diff --git a/sysdeps/unix/sysv/linux/readdir64_r.c b/sysdeps/unix/sysv/linux/readdir64_r.c
1303 -index 32962a176a..699d120b76 100644
1304 +index 5ae099bde7..b499388de7 100644
1305 --- a/sysdeps/unix/sysv/linux/readdir64_r.c
1306 +++ b/sysdeps/unix/sysv/linux/readdir64_r.c
1307 @@ -91,89 +91,44 @@ __old_readdir64_r (DIR *dirp, struct __old_dirent64 *entry,
1308 @@ -190,5 +190,5 @@ index 32962a176a..699d120b76 100644
1309
1310 compat_symbol (libc, __old_readdir64_r, readdir64_r, GLIBC_2_1);
1311 --
1312 -2.38.2
1313 +2.39.1
1314
1315
1316 diff --git a/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch b/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch
1317 index 7a9c5a3..644af1c 100644
1318 --- a/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch
1319 +++ b/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch
1320 @@ -1,8 +1,7 @@
1321 -From c71a60022adc7c9b7e37a813e2abad0d0724245a Mon Sep 17 00:00:00 2001
1322 +From b1ab50b1c7f17d6b38c1e3a665cca971ba16deab Mon Sep 17 00:00:00 2001
1323 From: Adhemerval Zanella <adhemerval.zanella@××××××.org>
1324 -Date: Tue, 20 Oct 2020 16:00:43 -0300
1325 -Subject: [PATCH 09/10] linux: Use getdents64 on readdir64 compat
1326 - implementation
1327 +Date: Fri, 27 Jan 2023 14:28:34 -0300
1328 +Subject: [PATCH 9/9] linux: Use getdents64 on readdir64 compat implementation
1329
1330 It uses a similar strategy from the non-LFS readdir that also
1331 uses getdents64 internally and uses a translation buffer to return
1332 @@ -12,14 +11,45 @@ It allows to remove __old_getdents64.
1333
1334 Checked on i686-linux-gnu.
1335 ---
1336 + sysdeps/unix/sysv/linux/dirstream.h | 13 +++-
1337 sysdeps/unix/sysv/linux/getdents64.c | 93 ----------------------------
1338 sysdeps/unix/sysv/linux/olddirent.h | 2 -
1339 - sysdeps/unix/sysv/linux/opendir.c | 15 ++++-
1340 - sysdeps/unix/sysv/linux/readdir64.c | 62 +++++++++++++++----
1341 - 4 files changed, 64 insertions(+), 108 deletions(-)
1342 + sysdeps/unix/sysv/linux/readdir64.c | 50 +++++++++++----
1343 + 4 files changed, 50 insertions(+), 108 deletions(-)
1344
1345 +diff --git a/sysdeps/unix/sysv/linux/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h
1346 +index 8f58a1c3a6..b03ece4590 100644
1347 +--- a/sysdeps/unix/sysv/linux/dirstream.h
1348 ++++ b/sysdeps/unix/sysv/linux/dirstream.h
1349 +@@ -24,6 +24,11 @@
1350 + #include <libc-lock.h>
1351 + #include <telldir.h>
1352 +
1353 ++#include <shlib-compat.h>
1354 ++#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
1355 ++# include <olddirent.h>
1356 ++#endif
1357 ++
1358 + /* Directory stream type.
1359 +
1360 + The miscellaneous Unix `readdir' implementations read directory data
1361 +@@ -44,7 +49,13 @@ struct __dirstream
1362 + int errcode; /* Delayed error code. */
1363 +
1364 + #if !defined __OFF_T_MATCHES_OFF64_T || !defined __INO_T_MATCHES_INO64_T
1365 +- struct dirent tdp;
1366 ++ union
1367 ++ {
1368 ++ struct dirent tdp;
1369 ++#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
1370 ++ struct __old_dirent64 tdp64;
1371 ++# endif
1372 ++ };
1373 + #endif
1374 + #if _DIRENT_OFFSET_TRANSLATION
1375 + struct dirstream_loc_t locs; /* off64_t to long int map for telldir. */
1376 diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
1377 -index 510a586859..92481526c5 100644
1378 +index 01c3517deb..db299864ed 100644
1379 --- a/sysdeps/unix/sysv/linux/getdents64.c
1380 +++ b/sysdeps/unix/sysv/linux/getdents64.c
1381 @@ -36,97 +36,4 @@ weak_alias (__getdents64, getdents64)
1382 @@ -121,7 +151,7 @@ index 510a586859..92481526c5 100644
1383 -# endif /* SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) */
1384 #endif /* _DIRENT_MATCHES_DIRENT64 */
1385 diff --git a/sysdeps/unix/sysv/linux/olddirent.h b/sysdeps/unix/sysv/linux/olddirent.h
1386 -index 00c84b9521..68aafd7c02 100644
1387 +index cde95e192e..2d682a6919 100644
1388 --- a/sysdeps/unix/sysv/linux/olddirent.h
1389 +++ b/sysdeps/unix/sysv/linux/olddirent.h
1390 @@ -36,8 +36,6 @@ extern struct __old_dirent64 *__old_readdir64_unlocked (DIR *__dirp)
1391 @@ -133,44 +163,11 @@ index 00c84b9521..68aafd7c02 100644
1392 int __old_scandir64 (const char * __dir,
1393 struct __old_dirent64 *** __namelist,
1394 int (*__selector) (const struct __old_dirent64 *),
1395 -diff --git a/sysdeps/unix/sysv/linux/opendir.c b/sysdeps/unix/sysv/linux/opendir.c
1396 -index 9a0b7ab4c4..df40b0a64e 100644
1397 ---- a/sysdeps/unix/sysv/linux/opendir.c
1398 -+++ b/sysdeps/unix/sysv/linux/opendir.c
1399 -@@ -23,6 +23,11 @@
1400 -
1401 - #include <not-cancel.h>
1402 -
1403 -+#include <shlib-compat.h>
1404 -+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
1405 -+# include <olddirent.h>
1406 -+#endif
1407 -+
1408 - enum {
1409 - opendir_oflags = O_RDONLY|O_NDELAY|O_DIRECTORY|O_LARGEFILE|O_CLOEXEC
1410 - };
1411 -@@ -128,7 +133,15 @@ __alloc_dir (int fd, bool close_fd, int flags,
1412 - expand the buffer if required. */
1413 - enum
1414 - {
1415 -- tbuffer_size = sizeof (struct dirent) + NAME_MAX + 1
1416 -+ tbuffer_size =
1417 -+# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
1418 -+ /* This is used on compat readdir64. */
1419 -+ MAX (sizeof (struct dirent),
1420 -+ sizeof (struct __old_dirent64))
1421 -+# else
1422 -+ sizeof (struct dirent)
1423 -+# endif
1424 -+ + NAME_MAX + 1
1425 - };
1426 - dirp->tbuffer = malloc (tbuffer_size);
1427 - if (dirp->tbuffer == NULL)
1428 diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
1429 -index bbe247f95d..01e834e238 100644
1430 +index b901071aa7..88e42c5e90 100644
1431 --- a/sysdeps/unix/sysv/linux/readdir64.c
1432 +++ b/sysdeps/unix/sysv/linux/readdir64.c
1433 -@@ -102,21 +102,52 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
1434 +@@ -102,21 +102,43 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
1435 # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
1436 # include <olddirent.h>
1437
1438 @@ -182,29 +179,20 @@ index bbe247f95d..01e834e238 100644
1439 +dirstream_old_entry (struct __dirstream *ds, const struct dirent64 *dp64)
1440 +{
1441 + /* Check for overflow. */
1442 -+ ino_t d_ino = dp64->d_ino;
1443 -+ if (d_ino != dp64->d_ino)
1444 ++ if (!in_ino_t_range (dp64->d_ino))
1445 + return false;
1446 +
1447 -+ /* Expand the translation buffer to hold the new namesize. */
1448 -+ size_t d_reclen = sizeof (struct __old_dirent64)
1449 -+ + dp64->d_reclen - offsetof (struct dirent64, d_name);
1450 -+ if (d_reclen > ds->tbuffer_size)
1451 -+ {
1452 -+ char *newbuffer = realloc (ds->tbuffer, d_reclen);
1453 -+ if (newbuffer == NULL)
1454 -+ return false;
1455 -+ ds->tbuffer = newbuffer;
1456 -+ ds->tbuffer_size = d_reclen;
1457 -+ }
1458 ++ /* And if name is too large. */
1459 ++ if (dp64->d_reclen - offsetof (struct dirent64, d_name) > NAME_MAX)
1460 ++ return false;
1461 +
1462 -+ struct __old_dirent64 *olddp64 = (struct __old_dirent64 *) ds->tbuffer;
1463 ++ ds->filepos = dp64->d_off;
1464 +
1465 -+ olddp64->d_off = dp64->d_off;
1466 -+ olddp64->d_ino = dp64->d_ino;
1467 -+ olddp64->d_reclen = dp64->d_reclen;
1468 -+ olddp64->d_type = dp64->d_type;
1469 -+ memcpy (olddp64->d_name, dp64->d_name,
1470 ++ ds->tdp64.d_off = dp64->d_off;
1471 ++ ds->tdp64.d_ino = dp64->d_ino;
1472 ++ ds->tdp64.d_reclen = dp64->d_reclen;
1473 ++ ds->tdp64.d_type = dp64->d_type;
1474 ++ memcpy (ds->tdp64.d_name, dp64->d_name,
1475 + dp64->d_reclen - offsetof (struct dirent64, d_name));
1476 +
1477 + return true;
1478 @@ -230,7 +218,7 @@ index bbe247f95d..01e834e238 100644
1479 if (bytes <= 0)
1480 {
1481 /* Linux may fail with ENOENT on some file systems if the
1482 -@@ -127,17 +158,24 @@ __old_readdir64_unlocked (DIR *dirp)
1483 +@@ -127,17 +149,21 @@ __old_readdir64_unlocked (DIR *dirp)
1484 __set_errno (saved_errno);
1485 return NULL;
1486 }
1487 @@ -251,15 +239,12 @@ index bbe247f95d..01e834e238 100644
1488 + /* Skip entries which might overflow d_ino or for memory allocation failure
1489 + in case of large file names. */
1490 + if (dirstream_old_entry (dirp, dp64))
1491 -+ {
1492 -+ dirp->filepos = dp64->d_off;
1493 -+ return (struct __old_dirent64 *) dirp->tbuffer;
1494 -+ }
1495 ++ return &dirp->tdp64;
1496 +
1497 + return NULL;
1498 }
1499
1500 attribute_compat_text_section
1501 --
1502 -2.38.2
1503 +2.39.1
1504
1505
1506 diff --git a/9999/0010-dirent-Deprecate-getdirentries.patch b/9999/0010-dirent-Deprecate-getdirentries.patch
1507 deleted file mode 100644
1508 index 28f744a..0000000
1509 --- a/9999/0010-dirent-Deprecate-getdirentries.patch
1510 +++ /dev/null
1511 @@ -1,100 +0,0 @@
1512 -From 2f0668caf22acf6493dce8dcfd670e4b35fb6892 Mon Sep 17 00:00:00 2001
1513 -From: Adhemerval Zanella <adhemerval.zanella@××××××.org>
1514 -Date: Fri, 17 Apr 2020 09:59:51 -0300
1515 -Subject: [PATCH 10/10] dirent: Deprecate getdirentries
1516 -
1517 -The interface has some issues:
1518 -
1519 - 1. It is build on top getdents on Linux and requires handling
1520 - non-LFS call using LFS getdents.
1521 -
1522 - 2. It is not wildly used and the non-LFS support is as problematic
1523 - as non-LFS readdir. glibc only exports the LFS getdents.
1524 -
1525 - 3. It is not a direct replacement over BSD since on some plataform
1526 - its signature has changed (FreeBSD 11, for instance, used to
1527 - set the offset as a 'long' and changed to 'off_t' on version 12).
1528 -
1529 -The idea is to eventually move the symbols to compat ones.
1530 ----
1531 - NEWS | 3 +++
1532 - dirent/dirent.h | 14 ++++++++++----
1533 - sysdeps/unix/sysv/linux/Makefile | 4 ++++
1534 - 3 files changed, 17 insertions(+), 4 deletions(-)
1535 -
1536 -diff --git a/NEWS b/NEWS
1537 -index a10bb08fb0..2b4ed6bbc1 100644
1538 ---- a/NEWS
1539 -+++ b/NEWS
1540 -@@ -21,6 +21,9 @@ Deprecated and removed features, and other changes affecting compatibility:
1541 - corresponds to the AT_PLATFORM system name, or employs the legacy AT_HWCAP
1542 - search mechanism, which was deprecated in version 2.33.
1543 -
1544 -+* The function getdirentries is now deprecated, applications should use
1545 -+ either getdents64, readdir64 or readdir.
1546 -+
1547 - Changes to build and runtime requirements:
1548 -
1549 - [Add changes to build and runtime requirements here]
1550 -diff --git a/dirent/dirent.h b/dirent/dirent.h
1551 -index c47d3273b2..1c299e5be8 100644
1552 ---- a/dirent/dirent.h
1553 -+++ b/dirent/dirent.h
1554 -@@ -350,29 +350,35 @@ extern int alphasort64 (const struct dirent64 **__e1,
1555 - /* Read directory entries from FD into BUF, reading at most NBYTES.
1556 - Reading starts at offset *BASEP, and *BASEP is updated with the new
1557 - position after reading. Returns the number of bytes read; zero when at
1558 -- end of directory; or -1 for errors. */
1559 -+ end of directory; or -1 for errors.
1560 -+ This is deprecated and getdents64 or readdir should be used instead. */
1561 - # ifndef __USE_FILE_OFFSET64
1562 - extern __ssize_t getdirentries (int __fd, char *__restrict __buf,
1563 - size_t __nbytes,
1564 - __off_t *__restrict __basep)
1565 -- __THROW __nonnull ((2, 4));
1566 -+ __THROW __nonnull ((2, 4))
1567 -+ __attribute_deprecated_msg__ ("Use getdents64 instead");
1568 - # else
1569 - # ifdef __REDIRECT
1570 - extern __ssize_t __REDIRECT_NTH (getdirentries,
1571 - (int __fd, char *__restrict __buf,
1572 - size_t __nbytes,
1573 - __off64_t *__restrict __basep),
1574 -- getdirentries64) __nonnull ((2, 4));
1575 -+ getdirentries64)
1576 -+ __nonnull ((2, 4))
1577 -+ __attribute_deprecated_msg__ ("Use getdents64 instead");
1578 - # else
1579 - # define getdirentries getdirentries64
1580 - # endif
1581 - # endif
1582 -
1583 - # ifdef __USE_LARGEFILE64
1584 -+/* This is deprecated and getdents64 or readdir64 should be used instead. */
1585 - extern __ssize_t getdirentries64 (int __fd, char *__restrict __buf,
1586 - size_t __nbytes,
1587 - __off64_t *__restrict __basep)
1588 -- __THROW __nonnull ((2, 4));
1589 -+ __THROW __nonnull ((2, 4))
1590 -+ __attribute_deprecated_msg__ ("Use getdents64 instead");
1591 - # endif
1592 - #endif /* Use misc. */
1593 -
1594 -diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
1595 -index f298878e8f..41e5341450 100644
1596 ---- a/sysdeps/unix/sysv/linux/Makefile
1597 -+++ b/sysdeps/unix/sysv/linux/Makefile
1598 -@@ -467,6 +467,10 @@ tests += \
1599 - tst-getdents64 \
1600 - tst-readdir64-compat \
1601 - # tests
1602 -+
1603 -+# Avoid the warning for the weak_alias for _DIRENT_MATCHES_DIRENT64
1604 -+CFLAGS-getdirentries64.o = -Wno-deprecated-declarations
1605 -+CFLAGS-getdirentries64.os = -Wno-deprecated-declarations
1606 - endif # $(subdir) == dirent
1607 -
1608 - ifeq ($(subdir),nis)
1609 ---
1610 -2.38.2
1611 -