GNU C Library master sources branch master updated. glibc-2.28.9000-374-g8d20a2f

fw@sourceware.org fw@sourceware.org
Mon Dec 10 15:41:00 GMT 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  8d20a2f414fa52aceef8a0e3675415df54a840db (commit)
      from  80472e2fba099c8da559bd524486354636ed0c4f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8d20a2f414fa52aceef8a0e3675415df54a840db

commit 8d20a2f414fa52aceef8a0e3675415df54a840db
Author: Florian Weimer <fweimer@redhat.com>
Date:   Mon Dec 10 14:14:45 2018 +0100

    compat getdents64: Use correct offset for retry [BZ #23972]
    
    d_off is the offset of the *next* entry, not the offset of the current
    entry.

diff --git a/ChangeLog b/ChangeLog
index 4d57829..1d21435 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2018-12-10  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #23972]
+	* sysdeps/unix/sysv/linux/getdents64.c (handle_overflow): Check
+	offset instead of count for clarity.  Fix typo in comment.
+	(__old_getdents64): Keep track of previous offset.  Use it to call
+	handle_overflow.
+	* sysdeps/unix/sysv/linux/tst-readdir64-compat.c (do_test): Check
+	that d_off is never zero.
+
 2018-12-10  Andreas Schwab  <schwab@suse.de>
 
 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/*-le.abilist: Move to
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
index bc140b5..46eb5f4 100644
--- a/sysdeps/unix/sysv/linux/getdents64.c
+++ b/sysdeps/unix/sysv/linux/getdents64.c
@@ -41,14 +41,14 @@ handle_overflow (int fd, __off64_t offset, ssize_t count)
 {
   /* If this is the first entry in the buffer, we can report the
      error.  */
-  if (count == 0)
+  if (offset == 0)
     {
       __set_errno (EOVERFLOW);
       return -1;
     }
 
   /* Otherwise, seek to the overflowing entry, so that the next call
-     will report the error, and return the data read so far..  */
+     will report the error, and return the data read so far.  */
   if (__lseek64 (fd, offset, SEEK_SET) != 0)
     return -1;
   return count;
@@ -70,6 +70,15 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
   ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
   if (retval > 0)
     {
+      /* This is the marker for the first entry.  Offset 0 is reserved
+	 for the first entry (see rewinddir).  Here, we use it as a
+	 marker for the first entry in the buffer.  We never actually
+	 seek to offset 0 because handle_overflow reports the error
+	 directly, so it does not matter that the offset is incorrect
+	 if entries have been read from the descriptor before (so that
+	 the descriptor is not actually at offset 0).  */
+      __off64_t previous_offset = 0;
+
       char *p = buf;
       char *end = buf + retval;
       while (p < end)
@@ -84,7 +93,7 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
 
 	  /* Check for ino_t overflow.  */
 	  if (__glibc_unlikely (ino != source->d_ino))
-	    return handle_overflow (fd, offset, p - buf);
+	    return handle_overflow (fd, previous_offset, p - buf);
 
 	  /* Convert to the target layout.  Use a separate struct and
 	     memcpy to side-step aliasing issues.  */
@@ -107,6 +116,7 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
 		     reclen - offsetof (struct dirent64, d_name));
 
 	  p += reclen;
+	  previous_offset = offset;
 	}
      }
   return retval;
diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
index 43c4a84..cb78bc9 100644
--- a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
+++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
@@ -88,6 +88,10 @@ do_test (void)
       else
         TEST_VERIFY_EXIT (entry_test != NULL);
 
+      /* d_off is never zero because it is the offset of the next
+         entry (not the current entry).  */
+      TEST_VERIFY (entry_reference->d_off > 0);
+
       /* Check that the entries are the same.  */
       TEST_COMPARE_BLOB (entry_reference->d_name,
                          strlen (entry_reference->d_name),

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                      |   10 ++++++++++
 sysdeps/unix/sysv/linux/getdents64.c           |   16 +++++++++++++---
 sysdeps/unix/sysv/linux/tst-readdir64-compat.c |    4 ++++
 3 files changed, 27 insertions(+), 3 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources



More information about the Glibc-cvs mailing list