diff options
author | Rich Felker <dalias@aerifal.cx> | 2018-07-18 13:25:48 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2018-07-18 13:34:34 -0400 |
commit | b3fa0f2b1b8c267c1cbe8c62464e484f3a174a4e (patch) | |
tree | 7d5c1d52617b69d62ddf4fbba48c2aaabeb8290a /src/dirent | |
parent | df6d9450ea19fd71e52cf5cdb4c85beb73066394 (diff) | |
download | musl-b3fa0f2b1b8c267c1cbe8c62464e484f3a174a4e.tar.gz musl-b3fa0f2b1b8c267c1cbe8c62464e484f3a174a4e.tar.bz2 musl-b3fa0f2b1b8c267c1cbe8c62464e484f3a174a4e.tar.xz musl-b3fa0f2b1b8c267c1cbe8c62464e484f3a174a4e.zip |
fix regression in alignment of dirent structs produced by readdir
commit 32482f61da7650ff10741bd5aedd66bbc3ea165b reduced the number of
int members before the dirent buf from 4 to 3, thereby misaligning it
mod sizeof(off_t), producing invalid accesses on any arch where
alignof(off_t)==sizeof(off_t).
rather than re-adding wasted padding, reorder the struct to meet the
requirement and add a comment and static assertion to prevent this
from getting broken again.
Diffstat (limited to 'src/dirent')
-rw-r--r-- | src/dirent/__dirent.h | 4 | ||||
-rw-r--r-- | src/dirent/readdir.c | 4 |
2 files changed, 7 insertions, 1 deletions
diff --git a/src/dirent/__dirent.h b/src/dirent/__dirent.h index 101b0368..828a5f17 100644 --- a/src/dirent/__dirent.h +++ b/src/dirent/__dirent.h @@ -1,9 +1,11 @@ struct __dirstream { - int fd; off_t tell; + int fd; int buf_pos; int buf_end; volatile int lock[1]; + /* Any changes to this struct must preserve the property: + * offsetof(struct __dirent, buf) % sizeof(off_t) == 0 */ char buf[2048]; }; diff --git a/src/dirent/readdir.c b/src/dirent/readdir.c index 2cf0632c..dc5f3edb 100644 --- a/src/dirent/readdir.c +++ b/src/dirent/readdir.c @@ -1,9 +1,13 @@ #include <dirent.h> #include <errno.h> +#include <stddef.h> #include "__dirent.h" #include "syscall.h" #include "libc.h" +typedef char dirstream_buf_alignment_check[1-2*(int)( + offsetof(struct __dirstream, buf) % sizeof(off_t))]; + int __getdents(int, struct dirent *, size_t); struct dirent *readdir(DIR *dir) |