This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
PATCH: Check d_ino and d_off sizes before using getdents syscall
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Thu, 17 May 2012 05:07:38 -0700
- Subject: PATCH: Check d_ino and d_off sizes before using getdents syscall
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
We have
struct kernel_dirent
{
long int d_ino;
__kernel_off_t d_off;
unsigned short int d_reclen;
char d_name[256];
};
and
struct dirent
{
#ifndef __USE_FILE_OFFSET64
__ino_t d_ino;
__off_t d_off;
#else
__ino64_t d_ino;
__off64_t d_off;
#endif
unsigned short int d_reclen;
unsigned char d_type;
char d_name[256]; /* We must not include limits.h! */
};
We can use the getdents system call only if kernel and user dirents have
the same d_ino and d_off sizes. On x32, they are different. This
patch adds a check. Tested on Linux/ia32, Linux/x86-64 and Linux/x32.
OK to install?
Thanks.
H.J.
* sysdeps/unix/sysv/linux/getdents.c (__GETDENTS): Use
getdents system call only if kernel and user dirents have the
same d_ino and d_off sizes.
diff --git a/sysdeps/unix/sysv/linux/getdents.c b/sysdeps/unix/sysv/linux/getdents.c
index eb9cfef..f31cf83 100644
--- a/sysdeps/unix/sysv/linux/getdents.c
+++ b/sysdeps/unix/sysv/linux/getdents.c
@@ -99,7 +99,13 @@ __GETDENTS (int fd, char *buf, size_t nbytes)
ssize_t retval;
#ifdef __ASSUME_GETDENTS32_D_TYPE
- if (sizeof (DIRENT_TYPE) == sizeof (struct dirent))
+ /* Sizes of d_ino and d_off in kernel_dirent and dirent must be the
+ same. */
+ if (sizeof (DIRENT_TYPE) == sizeof (struct dirent)
+ && (sizeof (((struct kernel_dirent *) 0)->d_ino)
+ == sizeof (((struct dirent *) 0)->d_ino))
+ && (sizeof (((struct kernel_dirent *) 0)->d_off)
+ == sizeof (((struct dirent *) 0)->d_off)))
{
retval = INLINE_SYSCALL (getdents, 3, fd, CHECK_N(buf, nbytes), nbytes);