![]() |
|
Message-ID: <20250710185131.186-1-mailto.luca.kellermann@gmail.com> Date: Thu, 10 Jul 2025 20:51:28 +0200 From: Luca Kellermann <mailto.luca.kellermann@...il.com> To: musl@...ts.openwall.com Subject: [PATCH 1/4] scandir: hide that errno is set to 0 POSIX.1-2024 requires that standard functions don't set errno to 0. commit dae17a1aaf25d8333e729173d86659066607d87d ensured that cmp() and the caller of scandir() cannot observe that errno is set to 0 internally. however, this was not yet the case for the sel() callback. the following program demonstrates the issue: #include <assert.h> #include <dirent.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> static int sel(const struct dirent *e) { /* XSH errno / XSH 2.3 Error Numbers: "No function in this * volume of POSIX.1-2024 shall set errno to [0 / zero]." */ assert(errno != 0); return 1; } int main(void) { /* XSH errno: "The value of errno in the initial thread shall * be zero at program startup [...]" */ assert(errno == 0); errno = 1; struct dirent **es = 0; int n = scandir(".", &es, sel, alphasort); if (n == -1) { perror("scandir"); exit(EXIT_FAILURE); } while (n > 0) free(es[--n]); free(es); } $ ./scandir-errno Assertion failed: errno != 0 (scandir-errno.c: sel: 10) Aborted (core dumped) --- src/dirent/scandir.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dirent/scandir.c b/src/dirent/scandir.c index 7456b9b8..eead7e50 100644 --- a/src/dirent/scandir.c +++ b/src/dirent/scandir.c @@ -17,7 +17,11 @@ int scandir(const char *path, struct dirent ***res, if (!d) return -1; while ((errno=0), (de = readdir(d))) { - if (sel && !sel(de)) continue; + if (sel) { + /* sel() must not observe that errno was set to 0. */ + errno = old_errno; + if (!sel(de)) continue; + } if (cnt >= len) { len = 2*len+1; if (len > SIZE_MAX/sizeof *names) break; @@ -37,6 +41,7 @@ int scandir(const char *path, struct dirent ***res, free(names); return -1; } + /* cmp() and caller must not observe that errno was set to 0. */ errno = old_errno; if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp); -- 2.43.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.