From patchwork Tue Aug 31 14:44:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 44826 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E54483857C7E for ; Tue, 31 Aug 2021 14:45:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E54483857C7E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1630421104; bh=oZy8W58IufMuAoLnpmQV4k7a96eGRGoHa3xbdFRjh/U=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=U9ZQ4kti2Y03W0J7MKk/Aa5bUZxq1ub7QwARSuDOFrPsSoqmN//RNw7K6Cwou7QVh ofejtwaQJwfqQ9RcqiOW/KW/BGdec9eXbLz/uZY/EauotLddbcch5IRGFomcHKGwVM burdkhIlYOeQtvBnCi+och6mHhhZsdUUxb/y35p0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qt1-x82b.google.com (mail-qt1-x82b.google.com [IPv6:2607:f8b0:4864:20::82b]) by sourceware.org (Postfix) with ESMTPS id 402633858409 for ; Tue, 31 Aug 2021 14:44:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 402633858409 Received: by mail-qt1-x82b.google.com with SMTP id d11so2105055qtw.3 for ; Tue, 31 Aug 2021 07:44:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=oZy8W58IufMuAoLnpmQV4k7a96eGRGoHa3xbdFRjh/U=; b=Obdf6+9spCPBmO88XNHTLzrg6sDR+45HFdg8b/c1rs27xO2haBC1/2pCVTp68LFPHD a62b+Hf1qKKp7MFMq1fzjq6yyIZ8OfX/f8B+zf4UhpoLnJg8XJOO7iiuSn+hDrHCHxSW rFyK//iTS697L/NDP6XZIsZQcBpMFarFlBZ+LKiv3G0gtCWnfMEF2saOAP0V/pHNXeNE U5sQyp/giM33FvMoU6YqKtpvxlXGgaeVNJ8lTqA0D+EEDKvWCcHezWwkeqppwnQqWr4h wLX+q/C/0gF5eRyqRBMpLVlXFc1j2/FI7wVXFKg8ivEDOzTsbu1jPCONM9iYHIAmScHy cVaw== X-Gm-Message-State: AOAM5309I9EKR7usJxC9GZNZv0l3yl/IGNEqQiXHRqRXnjom99rbB4Q9 QQ26bUT5DVzjbpet9OAbq+hKKdq3MT6FSQ== X-Google-Smtp-Source: ABdhPJy6D4MdnFZNWHS+d5bJM+uhz1DwCzc5G+0rdTlgp1ZUzRiAFTDX4mGJNxaKuyCAcAWYB5RAKg== X-Received: by 2002:ac8:4b4c:: with SMTP id e12mr3013170qts.295.1630421072633; Tue, 31 Aug 2021 07:44:32 -0700 (PDT) Received: from birita.. ([2804:431:c7ca:1a68:8724:3870:46f9:162b]) by smtp.gmail.com with ESMTPSA id z6sm13806556qke.24.2021.08.31.07.44.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Aug 2021 07:44:32 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v4] io: Fix ftw internal realloc buffer (BZ #28126) Date: Tue, 31 Aug 2021 11:44:28 -0300 Message-Id: <20210831144428.2405872-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Main change is to keep track of the number of subfolders created to avoid removing more if xmkdir bails early. D.J has pointed out that it fails on builbot and it seems that it due some maximum path limitation of the fuse-overlayfs filesystem which limits the maximum folder name of 252 and a total path less than 4096, which make the test no possible (since its idea is exactly to check for paths *longer* than PATH_MAX). I am not sure how to accomodate it for fuse-overlayfs, maybe making unsupported if mkdir fails. --- The 106ff08526d3ca did not take in consideration the buffer might be reallocated if the total path is larger than PATH_MAX. The realloc uses 'dirbuf', where 'dirstreams' is the allocated buffer. Checked on x86_64-linux-gnu. --- io/Makefile | 1 + io/ftw.c | 13 ++++--- io/tst-ftw-bz28126.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 io/tst-ftw-bz28126.c diff --git a/io/Makefile b/io/Makefile index 9871ecbc74..ecf65aba60 100644 --- a/io/Makefile +++ b/io/Makefile @@ -79,6 +79,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ tst-futimens \ tst-utimensat \ tst-closefrom \ + tst-ftw-bz28126 tests-time64 := \ tst-futimens-time64 \ diff --git a/io/ftw.c b/io/ftw.c index ce1c6a14a3..bb3ac0a7e0 100644 --- a/io/ftw.c +++ b/io/ftw.c @@ -392,13 +392,16 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name, if (data->dirbufsize < new_buflen) { /* Enlarge the buffer. */ - char *newp; - - data->dirbufsize = 2 * new_buflen; - newp = (char *) realloc (data->dirbuf, data->dirbufsize); + size_t newsize = 2 * new_buflen; + void *newp = realloc (data->dirstreams, data->maxdir + * sizeof (struct dir_data *) + + newsize); if (newp == NULL) return -1; - data->dirbuf = newp; + data->dirstreams = newp; + data->dirbufsize = newsize; + data->dirbuf = (char *) data->dirstreams + + data->maxdir * sizeof (struct dir_data *); } *((char *) __mempcpy (data->dirbuf + data->ftw.base, name, namlen)) = '\0'; diff --git a/io/tst-ftw-bz28126.c b/io/tst-ftw-bz28126.c new file mode 100644 index 0000000000..42b7123545 --- /dev/null +++ b/io/tst-ftw-bz28126.c @@ -0,0 +1,81 @@ +/* Check if internal buffer reallocation work for large paths (BZ #28126) + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int +my_func (const char *file, const struct stat *sb, int flag) +{ + return 0; +} + +static const char folder[NAME_MAX] = { [0 ... 253] = 'a', [254] = '\0' }; + +#define NSUBFOLDERS 16 +static int nsubfolders; + +static void +do_cleanup (void) +{ + xchdir (".."); + for (int i = 0; i < nsubfolders; i++) + { + remove (folder); + xchdir (".."); + } + remove (folder); +} +#define CLEANUP_HANDLER do_cleanup + +/* Check whether stack overflow occurs. */ +static int +do_test (void) +{ + char *tempdir = support_create_temp_directory ("tst-bz28126"); + + /* Create path with various subfolders to force an internal buffer + reallocation within ntfw. */ + char *path = xasprintf ("%s/%s", tempdir, folder); + xmkdir (path, 0777); + xchdir (path); + free (path); + for (int i = 0; i < NSUBFOLDERS - 1; i++) + { + xmkdir (folder, 0777); + xchdir (folder); + nsubfolders++; + } + + TEST_COMPARE (ftw (tempdir, my_func, 20), 0); + + free (tempdir); + + do_cleanup (); + + return 0; +} + +#include