Commit 59eaa63c9 for clamav.net
commit 59eaa63c9483709765e4efa12963ffebe07e3cec
Author: Val S. <valsnyde@cisco.com>
Date: Tue May 19 18:05:35 2026 -0400
Win32: fix opendir entry bounds handling (#1706)
opendir() copied up to PATH_MAX wide characters into DIR::entry
and then wrote the terminator one element past the end of the
buffer, leaving a fixed out-of-bounds write on success.
We do not believe this to be a security issue.
Copy at most entry_count - 1 characters, terminate the last
valid element, keep the append length check aligned with that
bound, and free DIR when uncpath() fails.
CLAM-2487
diff --git a/win32/compat/dirent.c b/win32/compat/dirent.c
index 7a5b0ded5..f705e1baf 100644
--- a/win32/compat/dirent.c
+++ b/win32/compat/dirent.c
@@ -33,6 +33,7 @@ DIR *opendir(const char *name)
DIR *d;
DWORD attrs;
int len;
+ const size_t entry_count = sizeof(d->entry) / sizeof(d->entry[0]);
struct stat sb;
wchar_t *wpath;
@@ -48,14 +49,16 @@ DIR *opendir(const char *name)
return NULL;
}
wpath = uncpath(name);
- if (!wpath)
+ if (!wpath) {
+ free(d);
return NULL;
- wcsncpy(d->entry, wpath, sizeof(d->entry) / sizeof(d->entry[0]));
+ }
+ wcsncpy(d->entry, wpath, entry_count - 1);
free(wpath);
- d->entry[sizeof(d->entry) / sizeof(d->entry[0])] = L'\0';
- len = wcslen(d->entry);
+ d->entry[entry_count - 1] = L'\0';
+ len = wcslen(d->entry);
- if (len >= sizeof(d->entry) / sizeof(d->entry[0]) - 4) {
+ if (len >= (int)entry_count - 4) {
free(d);
errno = ENAMETOOLONG;
return NULL;