Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250710185131.186-4-mailto.luca.kellermann@gmail.com>
Date: Thu, 10 Jul 2025 20:51:31 +0200
From: Luca Kellermann <mailto.luca.kellermann@...il.com>
To: musl@...ts.openwall.com
Subject: [PATCH 4/4] scandir: report ENOMEM and EOVERFLOW

if the loop is exited because len * sizeof *c.names does not fit into
size_t, errno should be explicitly set to ENOMEM. previously, the
behavior differed depending on which value errno happened to have at
this point.

if c.cnt reached a value > INT_MAX, scandir() returned an incorrect
value. EOVERFLOW should be reported instead.

it's unlikely that these errors can actually occur. it may not even
be possible to have directories with that many entries, and even then
malloc() or realloc() will probably fail long before len or c.cnt
reach those large values.
---
 src/dirent/scandir.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/dirent/scandir.c b/src/dirent/scandir.c
index 8883b9f8..07b54806 100644
--- a/src/dirent/scandir.c
+++ b/src/dirent/scandir.c
@@ -1,4 +1,5 @@
 #include <dirent.h>
+#include <limits.h>
 #include <pthread.h>
 #include <string.h>
 #include <stdlib.h>
@@ -46,9 +47,16 @@ int scandir(const char *path, struct dirent ***res,
 			errno = old_errno;
 			if (!sel(de)) continue;
 		}
+		if (c.cnt >= INT_MAX) {
+			errno = EOVERFLOW;
+			break;
+		}
 		if (c.cnt >= len) {
 			len = 2*len+1;
-			if (len > SIZE_MAX/sizeof *c.names) break;
+			if (len > SIZE_MAX/sizeof *c.names) {
+				errno = ENOMEM;
+				break;
+			}
 			tmp = realloc(c.names, len * sizeof *c.names);
 			if (!tmp) break;
 			c.names = tmp;
-- 
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.