am a37f3729: readdir: fix interface to kernel getdents64 function
* commit 'a37f3729730e4e7345977915d67adc3eea93dfe4':
readdir: fix interface to kernel getdents64 function
diff --git a/libc/unistd/opendir.c b/libc/unistd/opendir.c
index afa3ea0..f178bc6 100644
--- a/libc/unistd/opendir.c
+++ b/libc/unistd/opendir.c
@@ -92,6 +92,9 @@
_readdir_unlocked(DIR* dir)
{
struct dirent* entry;
+#ifndef NDEBUG
+ unsigned reclen;
+#endif
if ( !dir->_DIR_avail )
{
@@ -115,15 +118,18 @@
if (((long)(void*)entry & 3) != 0)
return NULL;
- if ( (unsigned)entry->d_reclen > sizeof(*entry) ||
- entry->d_reclen <= offsetof(struct dirent, d_name) )
+#ifndef NDEBUG
+ // paranoid testing of the interface with the kernel getdents64 system call
+ reclen = offsetof(struct dirent, d_name) + strlen(entry->d_name) + 1;
+ if ( reclen > sizeof(*entry) || reclen <= offsetof(struct dirent, d_name) )
goto Bad;
- if ( (char*)entry + entry->d_reclen > (char*)dir->_DIR_buff + sizeof(dir->_DIR_buff) )
+ if ( (char*)entry + reclen > (char*)dir->_DIR_buff + sizeof(dir->_DIR_buff) )
goto Bad;
- if ( !memchr( entry->d_name, 0, entry->d_reclen - offsetof(struct dirent, d_name)) )
+ if ( !memchr( entry->d_name, 0, reclen - offsetof(struct dirent, d_name)) )
goto Bad;
+#endif
dir->_DIR_next = (struct dirent*)((char*)entry + entry->d_reclen);
dir->_DIR_avail -= entry->d_reclen;