Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250721002322.703-4-mailto.luca.kellermann@gmail.com>
Date: Mon, 21 Jul 2025 02:23:22 +0200
From: Luca Kellermann <mailto.luca.kellermann@...il.com>
To: Rich Felker <dalias@...c.org>
Cc: Markus Wichmann <nullplan@....net>,
	musl@...ts.openwall.com
Subject: [PATCH v2 4/4] scandir: report ENOMEM and EOVERFLOW

if the loop is exited because len * sizeof *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 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 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 4f91af9c..9e4e623f 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>
@@ -32,9 +33,16 @@ int scandir(const char *path, struct dirent ***res,
 			errno = old_errno;
 			if (!sel(de)) continue;
 		}
+		if (cnt >= INT_MAX) {
+			errno = EOVERFLOW;
+			break;
+		}
 		if (cnt >= len) {
 			len = 2*len+1;
-			if (len > SIZE_MAX/sizeof *names) break;
+			if (len > SIZE_MAX/sizeof *names) {
+				errno = ENOMEM;
+				break;
+			}
 			tmp = realloc(names, len * sizeof *names);
 			if (!tmp) break;
 			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.