>From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Luca Kellermann Date: Sun, 12 Apr 2026 10:33:43 +0200 Subject: [PATCH v2] scandir: fix qsort usage calling qsort() with a pointer to a function whose type is not compatible with int(const void *, const void *) results in UB because qsort() would call this function with an incompatible type. avoid this by using qsort_r(). this is similar to how qsort() is implemented on top of qsort_r(). the casts to void * in wrapper_cmp() are required because the pointer to the comparison function for scandir() was (incorrectly) specified as int (*)(const struct dirent **, const struct dirent **) rather than int (*)(struct dirent *const *, struct dirent *const *) or int (*)(const struct dirent *const *, const struct dirent *const *). --- src/dirent/scandir.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dirent/scandir.c b/src/dirent/scandir.c index 9e4e623f686a80c08016e9582f8965520a4f2ba7..bcbb49dee7c546bea7a0ffc8ceba029b257f4a14 100644 --- a/src/dirent/scandir.c +++ b/src/dirent/scandir.c @@ -7,6 +7,12 @@ #include #include +static int wrapper_cmp(const void *de1, const void *de2, void *cmp) +{ + return ((int (*)(const struct dirent **, const struct dirent **))cmp)( + (void *)de1, (void *)de2); +} + int scandir(const char *path, struct dirent ***res, int (*sel)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **)) @@ -70,7 +76,7 @@ int scandir(const char *path, struct dirent ***res, /* 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); + if (cmp) __qsort_r(names, cnt, sizeof *names, wrapper_cmp, (void *)cmp); *res = names; return cnt; }