summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes3
-rw-r--r--eio.c13
2 files changed, 10 insertions, 6 deletions
diff --git a/Changes b/Changes
index 3bc3388..2685024 100644
--- a/Changes
+++ b/Changes
@@ -36,4 +36,5 @@ TODO: openbsd requires stdint.h for intptr_t - why posix?
- use _POSIX_MEMLOCK_RANGE for mlock.
- do not (errornously) overwrite CFLAGS in configure.ac.
- mknod used int3 for dev_t (ยง2 bit), not offs (64 bit).
-
+ - fix memory corruption in eio_readdirx for the flags
+ combination EIO_READDIR_STAT_ORDER | EIO_READDIR_DIRS_FIRST.
diff --git a/eio.c b/eio.c
index b303299..2123996 100644
--- a/eio.c
+++ b/eio.c
@@ -1062,8 +1062,10 @@ eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self)
static signed char
eio_dent_cmp (const eio_dirent *a, const eio_dirent *b)
{
- return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */
- : a->inode < b->inode ? -1 : a->inode > b->inode ? 1 : 0;
+ return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */
+ : a->inode < b->inode ? -1
+ : a->inode > b->inode ? 1
+ : 0;
}
#define EIO_DENT_CMP(i,op,j) eio_dent_cmp (&i, &j) op 0
@@ -1079,8 +1081,8 @@ eio_dent_radix_sort (eio_dirent *dents, int size, signed char score_bits, ino_t
assert (CHAR_BIT == 8);
assert (sizeof (eio_dirent) * 8 < 256);
- assert (offsetof (eio_dirent, inode)); /* we use 0 as sentinel */
- assert (offsetof (eio_dirent, score)); /* we use 0 as sentinel */
+ assert (offsetof (eio_dirent, inode)); /* we use bit #0 as sentinel */
+ assert (offsetof (eio_dirent, score)); /* we use bit #0 as sentinel */
if (size <= EIO_SORT_FAST)
return;
@@ -1245,6 +1247,7 @@ eio__scandir (eio_req *req, etp_worker *self)
X_LOCK (wrklock);
/* the corresponding closedir is in ETP_WORKER_CLEAR */
self->dirp = dirp = opendir (req->ptr1);
+
req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE;
req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0;
req->ptr2 = names = malloc (namesalloc);
@@ -1266,7 +1269,7 @@ eio__scandir (eio_req *req, etp_worker *self)
req->result = dentoffs;
if (flags & EIO_READDIR_STAT_ORDER)
- eio_dent_sort (dents, dentoffs, 0, inode_bits); /* sort by inode exclusively */
+ eio_dent_sort (dents, dentoffs, flags & EIO_READDIR_DIRS_FIRST ? 7 : 0, inode_bits);
else if (flags & EIO_READDIR_DIRS_FIRST)
if (flags & EIO_READDIR_FOUND_UNKNOWN)
eio_dent_sort (dents, dentoffs, 7, inode_bits); /* sort by score and inode */