Bug#180065: I'm running with this patch successfuly
I have successfully rebuilt glibc 2.3 with this dpatch. I verified that
readdir01 passes on a mounted IRIX NFS directory. I can now see all
9000 linux-kernel messages in my maildir again. :)
glibc23-getdents-fix.dpatch:
---------------------------
#! /bin/sh -e
# All lines beginning with `# DP:' are a description of the patch.
# DP: Fix the overflow detection in the getdents code
if [ $# -ne 2 ]; then
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
fi
case "$1" in
-patch) patch -d "$2" -f --no-backup-if-mismatch -p1 < $0;;
-unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p1 < $0;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
esac
exit 0
# append the patch here and adjust the -p? flag in the patch calls.
--- glibc-2.3.1/sysdeps/unix/sysv/linux/getdents.c~ 2003-02-10 10:19:12.000000000 -0600
+++ glibc-2.3.1/sysdeps/unix/sysv/linux/getdents.c 2003-02-10 10:20:09.000000000 -0600
@@ -47,6 +47,7 @@
#endif
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#define test_overflow(VAR, SIZE) ((((VAR) < 0 ? -(VAR):(VAR)) >> 8*(SIZE)) != 0)
extern int __syscall_getdents (int fd, char *__unbounded buf, unsigned int nbytes);
extern int __syscall_getdents64 (int fd, char *__unbounded buf, unsigned int nbytes);
@@ -97,7 +98,6 @@
internal_function
__GETDENTS (int fd, char *buf, size_t nbytes)
{
- off64_t last_offset = -1;
ssize_t retval;
#ifdef __NR_getdents64
@@ -129,6 +129,7 @@
if (retval != -1 || (errno != EINVAL && errno != ENOSYS))
# endif
{
+ int64_t last_offset = 0;
const size_t size_diff = (offsetof (struct kernel_dirent64, d_name)
- offsetof (DIRENT_TYPE, d_name));
@@ -176,7 +177,7 @@
if ((sizeof (outp->u.d_ino) != sizeof (inp->k.d_ino)
&& outp->u.d_ino != d_ino)
|| (sizeof (outp->u.d_off) != sizeof (inp->k.d_off)
- && outp->u.d_off != d_off))
+ && test_overflow(d_off, sizeof(outp->u.d_off))))
{
/* Overflow. If there was at least one entry
before this one, return them without error,
@@ -210,6 +211,7 @@
{
size_t red_nbytes;
struct kernel_dirent *skdp, *kdp;
+ __kernel_off_t last_offset = 0;
const size_t size_diff = (offsetof (DIRENT_TYPE, d_name)
- offsetof (struct kernel_dirent, d_name));
--
Nate Straz nstraz@sgi.com
sgi, inc http://www.sgi.com/
Linux Test Project http://ltp.sf.net/
Reply to: