From patchwork Sat Aug 8 08:46:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaoming Ni X-Patchwork-Id: 40236 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 82D453844079; Sat, 8 Aug 2020 08:47:02 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from huawei.com (szxga05-in.huawei.com [45.249.212.191]) by sourceware.org (Postfix) with ESMTPS id 8A835385DC35; Sat, 8 Aug 2020 08:46:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8A835385DC35 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nixiaoming@huawei.com Received: from DGGEMS402-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 251A47AB178297E9CFD2; Sat, 8 Aug 2020 16:46:53 +0800 (CST) Received: from use12-sp2.huawei.com (10.67.189.174) by DGGEMS402-HUB.china.huawei.com (10.3.19.202) with Microsoft SMTP Server id 14.3.487.0; Sat, 8 Aug 2020 16:46:42 +0800 From: Xiaoming Ni To: , , , , , , Subject: [PATCH] io:nftw/ftw:fix stack overflow when large nopenfd [BZ #26353] Date: Sat, 8 Aug 2020 16:46:40 +0800 Message-ID: <20200808084640.49174-1-nixiaoming@huawei.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Originating-IP: [10.67.189.174] X-CFilter-Loop: Reflected X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_MANYTO, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Cc: wangle6@huawei.com, nixiaoming@huawei.com Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" In ftw_startup(), call alloca to apply for a large amount of stack space. When descriptors is very large, stack overflow is triggered. BZ #26353 To fix the problem: 1. Set the upper limit of descriptors to getdtablesize(). 2. Replace alloca() in ftw_startup() with malloc(). --- io/Makefile | 3 ++- io/ftw.c | 19 +++++++++++++++++-- io/tst-bz26353.c | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 io/tst-bz26353.c diff --git a/io/Makefile b/io/Makefile index cf380f3516..0f674c317f 100644 --- a/io/Makefile +++ b/io/Makefile @@ -74,7 +74,8 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ tst-posix_fallocate tst-posix_fallocate64 \ tst-fts tst-fts-lfs tst-open-tmpfile \ tst-copy_file_range tst-getcwd-abspath tst-lockf \ - tst-ftw-lnk tst-file_change_detection tst-lchmod + tst-ftw-lnk tst-file_change_detection tst-lchmod \ + tst-bz26353 # Likewise for statx, but we do not need static linking here. tests-internal += tst-statx diff --git a/io/ftw.c b/io/ftw.c index 8c79d29a9e..094aada50c 100644 --- a/io/ftw.c +++ b/io/ftw.c @@ -643,18 +643,32 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, __set_errno (ENOENT); return -1; } + if (descriptors > getdtablesize()) + { + __set_errno (EINVAL); + return -1; + } data.maxdir = descriptors < 1 ? 1 : descriptors; data.actdir = 0; - data.dirstreams = (struct dir_data **) alloca (data.maxdir + data.dirstreams = (struct dir_data **) malloc (data.maxdir * sizeof (struct dir_data *)); + if (data.dirstreams == NULL) + { + __set_errno (ENOMEM); + return -1; + } memset (data.dirstreams, '\0', data.maxdir * sizeof (struct dir_data *)); /* PATH_MAX is always defined when we get here. */ data.dirbufsize = MAX (2 * strlen (dir), PATH_MAX); data.dirbuf = (char *) malloc (data.dirbufsize); if (data.dirbuf == NULL) - return -1; + { + free (data.dirstreams); + __set_errno (ENOMEM); + return -1; + } cp = __stpcpy (data.dirbuf, dir); /* Strip trailing slashes. */ while (cp > data.dirbuf + 1 && cp[-1] == '/') @@ -805,6 +819,7 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, __tdestroy (data.known_objects, free); free (data.dirbuf); __set_errno (save_err); + free (data.dirstreams); return result; } diff --git a/io/tst-bz26353.c b/io/tst-bz26353.c new file mode 100644 index 0000000000..4ab3d4b61f --- /dev/null +++ b/io/tst-bz26353.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include + +int my_func(const char *file , const struct stat *sb ,int flag) +{ + printf("%s\n", file); + return 0; +} + +int main(int argc, char *argv[]) +{ + mkdir("./tst-bz26353", 0755); + /*Check whether stack overflow occurs*/ + ftw("./tst-bz26353", my_func, 8192*1024); + rmdir("./tst-bz26353"); + return 0; +}