Pārlūkot izejas kodu

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.
Rich Felker 6 gadi atpakaļ
vecāks
revīzija
b3fa0f2b1b
2 mainītis faili ar 7 papildinājumiem un 1 dzēšanām
  1. 3 1
      src/dirent/__dirent.h
  2. 4 0
      src/dirent/readdir.c

+ 3 - 1
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];
 };

+ 4 - 0
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)