]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
scandir: fix wrong assumption about errno [BZ #17804]
authorAurelien Jarno <aurelien@aurel32.net>
Fri, 29 Dec 2017 13:44:57 +0000 (14:44 +0100)
committerAurelien Jarno <aurelien@aurel32.net>
Fri, 29 Dec 2017 13:45:35 +0000 (14:45 +0100)
malloc and realloc may set errno to ENOMEM even if they are successful.
The scandir code wrongly assume that they do not change errno, this
causes scandir to fail with ENOMEM even if malloc succeed.

The code already handles that readdir might set errno by calling
__set_errno (0) to clear the error. Move that part at the end of the
loop to also take malloc and realloc into account.

Changelog:
[BZ #17804]
* dirent/scandir-tail.c (SCANDIR_TAIL): Move __set_errno (0) at the
end of the loop. Improve comments.

ChangeLog
dirent/scandir-tail.c

index f87bc14690a7d048bd9b2516c12622fb993ab7ea..fd9a8dd2f5da4311ad483b0069156643312d2f41 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-29  Aurelien Jarno  <aurelien@aurel32.net>
+
+       [BZ #17804]
+       * dirent/scandir-tail.c (SCANDIR_TAIL): Move __set_errno (0) at the
+       end of the loop. Improve comments.
+
 2017-12-29  Zack Weinberg  <zackw@panix.com>
 
        [BZ #22615]
index 068c644c4efe350aea9489ea5406f40b67bdea37..a02c99a82837faf7f836bf545229cfaf5392b8da 100644 (file)
@@ -53,16 +53,14 @@ SCANDIR_TAIL (DIR *dp,
         {
           int selected = (*select) (d);
 
-         /* The SELECT function might have changed errno.  It was
-            zero before and it need to be again to make the later
-            tests work.  */
+         /* The SELECT function might have set errno to non-zero on
+            success.  It was zero before and it needs to be again to
+            make the later tests work.  */
          __set_errno (0);
 
           if (!selected)
             continue;
         }
-      else
-        __set_errno (0);
 
       if (__glibc_unlikely (c.cnt == vsize))
         {
@@ -81,6 +79,11 @@ SCANDIR_TAIL (DIR *dp,
       if (vnew == NULL)
         break;
       v[c.cnt++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize);
+
+      /* Ignore errors from readdir, malloc or realloc.  These functions
+        might have set errno to non-zero on success.  It was zero before
+        and it needs to be again to make the latter tests work.  */
+      __set_errno (0);
     }
 
   if (__glibc_likely (errno == 0))