Author: nieklinnenbank Date: Mon Jun 29 14:15:26 2009 New Revision: 170 Modified: trunk/lib/libposix/dirent.cpp Log: Fixed memory corruption in opendir() in libposix. The opendir() function did not correctly use the return value of read() to obtain the number of Dirent entries returned by the filesystem: it used st.st_size and caused it to perform operations out of bounds. Additionally, opendir() now preallocates 1024 Dirent entries. Modified: trunk/lib/libposix/dirent.cpp ============================================================================== --- trunk/lib/libposix/dirent.cpp (original) +++ trunk/lib/libposix/dirent.cpp Mon Jun 29 14:15:26 2009 @@ -45,18 +45,20 @@ return (ZERO); } /* Allocate Dirents. */ - dirent = new Dirent[st.st_size / sizeof(Dirent)]; + dirent = new Dirent[1024]; + memset(dirent, 0, 1024 * sizeof(Dirent)); /* Allocate DIR object. */ dir = new DIR; dir->fd = fd; - dir->buffer = new struct dirent[st.st_size / sizeof(Dirent)]; + dir->buffer = new struct dirent[1024]; + memset(dir->buffer, 0, 1024 * sizeof(struct dirent)); dir->current = 0; dir->count = 0; dir->eof = false; /* Read them all. */ - if ((e = read(fd, dirent, sizeof(Dirent) * st.st_size)) < 0) + if ((e = read(fd, dirent, sizeof(Dirent) * 1024)) < 0) { e = errno; closedir(dir); @@ -64,7 +66,7 @@ return (ZERO); } /* Fill in the dirent structs. */ - for (Size i = 0; i < st.st_size / sizeof(Dirent); i++) + for (Size i = 0; i < e / sizeof(Dirent); i++) { u8 types[] = { @@ -76,8 +78,8 @@ DT_FIFO, DT_SOCK, }; - strlcpy(dir->buffer[i].d_name, dirent[i].name, DIRLEN); - dir->buffer[i].d_type = types[dirent[i].type]; + strlcpy((dir->buffer)[i].d_name, dirent[i].name, DIRLEN); + (dir->buffer)[i].d_type = types[dirent[i].type]; } dir->count = e / sizeof(Dirent); delete dirent;