From patchwork Sat Aug 15 07:08:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaoming Ni X-Patchwork-Id: 1345238 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=huawei.com Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BTBHt0Ds1z9sTH for ; Sat, 15 Aug 2020 17:09:13 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7023038708D2; Sat, 15 Aug 2020 07:09:07 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from huawei.com (szxga06-in.huawei.com [45.249.212.32]) by sourceware.org (Postfix) with ESMTPS id 69C843857C4A; Sat, 15 Aug 2020 07:09:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 69C843857C4A 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 DGGEMS410-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 90A564CD1ECDBD833C5D; Sat, 15 Aug 2020 15:09:00 +0800 (CST) Received: from use12-sp2.huawei.com (10.67.189.174) by DGGEMS410-HUB.china.huawei.com (10.3.19.210) with Microsoft SMTP Server id 14.3.487.0; Sat, 15 Aug 2020 15:08:53 +0800 From: Xiaoming Ni To: , , , , , Subject: [PATCH v2] io:nftw/ftw:fix stack overflow when large nopenfd [BZ #26353] Date: Sat, 15 Aug 2020 15:08:51 +0800 Message-ID: <20200815070851.46403-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=-0.8 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, UNWANTED_LANGUAGE_BODY 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(). v2: not set errno after malloc fails. add check ftw return value on testcase add more testcase v1: https://public-inbox.org/libc-alpha/20200808084640.49174-1-nixiaoming@huawei.com/ --- io/Makefile | 3 ++- io/ftw.c | 15 +++++++++++++-- io/tst-bz26353.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 49 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..f8771a257b 100644 --- a/io/ftw.c +++ b/io/ftw.c @@ -643,18 +643,28 @@ 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) + 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); + return -1; + } cp = __stpcpy (data.dirbuf, dir); /* Strip trailing slashes. */ while (cp > data.dirbuf + 1 && cp[-1] == '/') @@ -805,6 +815,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..53e71bfe5e --- /dev/null +++ b/io/tst-bz26353.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include + +int my_func(const char *file, const struct stat *sb ,int flag) +{ + printf ("%s\n", file); + return 0; +} + +/*Check whether stack overflow occurs*/ +int do_test(int large_nopenfd) +{ + int ret = ftw("./tst-bz26353", my_func, large_nopenfd); + printf ("test big num %d, ret=%d errno=%d\n", large_nopenfd, ret, errno); + if (ret != -1 || errno != EINVAL) + return 1; + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + mkdir ("./tst-bz26353", 0755); + ret += do_test(getdtablesize() + 1); + ret += do_test(8192 * 1024); + ret += do_test(INT_MAX); + rmdir ("./tst-bz26353"); + return ret; +}