From patchwork Fri Dec 22 19:31:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 25080 Received: (qmail 128148 invoked by alias); 22 Dec 2017 19:31:09 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 127369 invoked by uid 89); 22 Dec 2017 19:31:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy= X-HELO: hall.aurel32.net From: Aurelien Jarno To: libc-alpha@sourceware.org Cc: Aurelien Jarno Subject: [PATCH v2 3/3] scandir: fix wrong assumption about errno [BZ #17804] Date: Fri, 22 Dec 2017 20:31:01 +0100 Message-Id: <20171222193101.3396-4-aurelien@aurel32.net> In-Reply-To: <20171222193101.3396-1-aurelien@aurel32.net> References: <20171222193101.3396-1-aurelien@aurel32.net> 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 | 6 ++++++ dirent/scandir-tail.c | 13 ++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8368b3006d..713c5ade6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-12-22 Aurelien Jarno + + [BZ #17804] + * dirent/scandir-tail.c (SCANDIR_TAIL): Move __set_errno (0) at the + end of the loop. Improve comments. + 2017-12-22 Zack Weinberg [BZ #22615] diff --git a/dirent/scandir-tail.c b/dirent/scandir-tail.c index 068c644c4e..927791fad0 100644 --- a/dirent/scandir-tail.c +++ b/dirent/scandir-tail.c @@ -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 need 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 need to be again to make the latter tests work. */ + __set_errno (0); } if (__glibc_likely (errno == 0))