From patchwork Tue Dec 29 19:34:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1421238 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=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=UcHYnhG2; dkim-atps=neutral Received: from sourceware.org (unknown [8.43.85.97]) (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 4D54Ps0kcjz9sVb for ; Wed, 30 Dec 2020 06:35:13 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6BA3B388A41D; Tue, 29 Dec 2020 19:35:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6BA3B388A41D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1609270505; bh=2haO1PVlnrg9WnLUuvvVeIBVkdqNRleLpq3OaY6uP6Y=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=UcHYnhG2gD305Yh9IXZjLctyva3z3ubeIXfVnQAiTrhEeZ8lzyTT7rdh5tMaCuRnx XFamljX3CumkVJJvds+puUe0ljh1Vn6DtiV8UVZV2HzxSA6I+WZWasj0VwqijkFQWE I3AkTqlQk3oScxMyijSORc+uM1w4G90n9RzcIF/g= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by sourceware.org (Postfix) with ESMTPS id 598E33857010 for ; Tue, 29 Dec 2020 19:35:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 598E33857010 Received: by mail-qv1-xf35.google.com with SMTP id 4so6811853qvh.1 for ; Tue, 29 Dec 2020 11:35:02 -0800 (PST) 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=2haO1PVlnrg9WnLUuvvVeIBVkdqNRleLpq3OaY6uP6Y=; b=ldqLTzfFPTrT07+6ecUYXdsn0MrO50MwMNa9zQMW3lb8mL/JoyCQAgd8xhNkB/0Gwx BaqM+Y7RKxNNcHK6B/TSn56C5UHVxTuyKcXLWqHrAxrURUJ5o9GlCbb7WEUT7WIkuJTl r5D4FMHB2lkpmv6wYXVjvfvEfigNwosBItFGGaugO/02xmml4Dk/k1qhfDYYhWE8tOn0 sXxIauvv68Ig7/ZZjBne13Y9m2HumUKXah0LsJ/BRem3yqr15B+rhre8xtYSPqsEhzjK K1Bs358FA0Y5Ek+DlygwjDs1UJL0JSB9XCnxDLeMipUWMMXqzKJQD6z+is/V/5+Wc75G UlpA== X-Gm-Message-State: AOAM5306FBA+uFy6AbXJHX9MK1YyLlTgop5D8sgBnnrbnThQztEzCjSz q/DTtj1dw193rEZOnSFxIXk8TpPsBbN+2Q== X-Google-Smtp-Source: ABdhPJyXgNPowLCQ1H2NPMTI8Z8aR32uJagIyfoE5kg/KCVmCdlTueVg6r1i5lCCDqIKMEpoX6J+8g== X-Received: by 2002:a0c:f2cd:: with SMTP id c13mr53504295qvm.11.1609270501686; Tue, 29 Dec 2020 11:35:01 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b14sm25383428qtx.36.2020.12.29.11.35.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Dec 2020 11:35:01 -0800 (PST) To: libc-alpha@sourceware.org, Paul Eggert Subject: [PATCH v3 1/6] Import idx.h from gnulib Date: Tue, 29 Dec 2020 16:34:49 -0300 Message-Id: <20201229193454.34558-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201229193454.34558-1-adhemerval.zanella@linaro.org> References: <20201229193454.34558-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 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.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: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: bug-gnulib@gnu.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" And use to simplify stdlib/canonicalize.c implementation. --- include/idx.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 include/idx.h diff --git a/include/idx.h b/include/idx.h new file mode 100644 index 0000000000..024b44ae98 --- /dev/null +++ b/include/idx.h @@ -0,0 +1,114 @@ +/* A type for indices and sizes. + Copyright (C) 2020 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 + . */ + +#ifndef _IDX_H +#define _IDX_H + +/* Get ptrdiff_t. */ +#include + +/* Get PTRDIFF_MAX. */ +#include + +/* The type 'idx_t' holds an (array) index or an (object) size. + Its implementation promotes to a signed integer type, + which can hold the values + 0..2^63-1 (on 64-bit platforms) or + 0..2^31-1 (on 32-bit platforms). + + Why a signed integer type? + + * Security: Signed types can be checked for overflow via + '-fsanitize=undefined', but unsigned types cannot. + + * Comparisons without surprises: ISO C99 § 6.3.1.8 specifies a few + surprising results for comparisons, such as + + (int) -3 < (unsigned long) 7 => false + (int) -3 < (unsigned int) 7 => false + and on 32-bit machines: + (long) -3 < (unsigned int) 7 => false + + This is surprising because the natural comparison order is by + value in the realm of infinite-precision signed integers (ℤ). + + The best way to get rid of such surprises is to use signed types + for numerical integer values, and use unsigned types only for + bit masks and enums. + + Why not use 'size_t' directly? + + * Because 'size_t' is an unsigned type, and a signed type is better. + See above. + + Why not use 'ptrdiff_t' directly? + + * Maintainability: When reading and modifying code, it helps to know that + a certain variable cannot have negative values. For example, when you + have a loop + + int n = ...; + for (int i = 0; i < n; i++) ... + + or + + ptrdiff_t n = ...; + for (ptrdiff_t i = 0; i < n; i++) ... + + you have to ask yourself "what if n < 0?". Whereas in + + idx_t n = ...; + for (idx_t i = 0; i < n; i++) ... + + you know that this case cannot happen. + + Similarly, when a programmer writes + + idx_t = ptr2 - ptr1; + + there is an implied assertion that ptr1 and ptr2 point into the same + object and that ptr1 <= ptr2. + + * Being future-proof: In the future, range types (integers which are + constrained to a certain range of values) may be added to C compilers + or to the C standard. Several programming languages (Ada, Haskell, + Common Lisp, Pascal) already have range types. Such range types may + help producing good code and good warnings. The type 'idx_t' could + then be typedef'ed to a range type that is signed after promotion. */ + +/* In the future, idx_t could be typedef'ed to a signed range type. + The clang "extended integer types", supported in Clang 11 or newer + , + are a special case of range types. However, these types don't support binary + operators with plain integer types (e.g. expressions such as x > 1). + Therefore, they don't behave like signed types (and not like unsigned types + either). So, we cannot use them here. */ + +/* Use the signed type 'ptrdiff_t'. */ +/* Note: ISO C does not mandate that 'size_t' and 'ptrdiff_t' have the same + size, but it is so on all platforms we have seen since 1990. */ +typedef ptrdiff_t idx_t; + +/* IDX_MAX is the maximum value of an idx_t. */ +#define IDX_MAX PTRDIFF_MAX + +/* So far no need has been found for an IDX_WIDTH macro. + Perhaps there should be another macro IDX_VALUE_BITS that does not + count the sign bit and is therefore one less than PTRDIFF_WIDTH. */ + +#endif /* _IDX_H */ From patchwork Tue Dec 29 19:34:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1421239 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=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=j9R4HGuv; dkim-atps=neutral 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 4D54Px5t4cz9sVb for ; Wed, 30 Dec 2020 06:35:17 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F34A3388A43A; Tue, 29 Dec 2020 19:35:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F34A3388A43A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1609270506; bh=UVf+JPK8wCFw72LCV+7v7ioEUFedK6SGQCrfpwt75KI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=j9R4HGuvyqHoPPcPpRB8Bm0uYe3SI5ZyewWBKNyomEHdLpcrsI1Z0SPxod2RJnuYU iYiXcuPCsm61tyMZvrqXX8UJ0ooruuW5d5IyxM3k03AFe4GpWivet3Cy2+fKRGnUe6 kqcxS791Y6sLzI7mZzD1B+I7tYT3tKTCwG4UA0BM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qv1-xf30.google.com (mail-qv1-xf30.google.com [IPv6:2607:f8b0:4864:20::f30]) by sourceware.org (Postfix) with ESMTPS id F3781386101F for ; Tue, 29 Dec 2020 19:35:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org F3781386101F Received: by mail-qv1-xf30.google.com with SMTP id j18so6791069qvu.3 for ; Tue, 29 Dec 2020 11:35:03 -0800 (PST) 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=UVf+JPK8wCFw72LCV+7v7ioEUFedK6SGQCrfpwt75KI=; b=eOAcxIMyGwUSBY+ITtb7/7eYYzQXu4Qw7mDbQZGJ/BprM7RKATdXWe36ysVIt1H3Ld K9YgnLQQ2+Ygq+U32FASaQGFkGjUsYblzmuLvgG0SYVc/9jlE9QOdGcNBo/MLs6dvL6B XtH2HNSUHqRZWvJYg/g5s/xcFtMsfesGwVOjtxjvyCoMMRDQhqz5dPQD+KXDHjl9YRMQ mwmxaa0ZQ+OPXtgsMY5NCbsJrCkBj9X0nr7XsLfmmP0KPECnLMHG/JAVtdFuKMCmoBav hYC4eVCkFREvhOLMkoKTPyf7tCFZo2+A7vD/D0C8dq2fKuH543/d2VZaYoaqmNJjP3C0 dxjw== X-Gm-Message-State: AOAM533mJD/6+GQEWmsIWCNZZiclo+GHLjfc/x2LOcoxC24euuJJkHyf hJUPBM7YRyv9bwPrrIva2hl03J/ATU3gfA== X-Google-Smtp-Source: ABdhPJyPURKp2oj+bgeA4ldL5GTM1L2RtVlCacixcGRZJZdUGbcIX28yGB+B6oAxa5dYbcP2yXSKBA== X-Received: by 2002:a0c:f1ce:: with SMTP id u14mr52803427qvl.24.1609270503372; Tue, 29 Dec 2020 11:35:03 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b14sm25383428qtx.36.2020.12.29.11.35.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Dec 2020 11:35:02 -0800 (PST) To: libc-alpha@sourceware.org, Paul Eggert Subject: [PATCH v3 2/6] Import filename.h from gnulib Date: Tue, 29 Dec 2020 16:34:50 -0300 Message-Id: <20201229193454.34558-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201229193454.34558-1-adhemerval.zanella@linaro.org> References: <20201229193454.34558-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 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.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: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: bug-gnulib@gnu.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" And use to simplify stdlib/canonicalize.c implementation. --- include/filename.h | 110 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 include/filename.h diff --git a/include/filename.h b/include/filename.h new file mode 100644 index 0000000000..4598fb1d63 --- /dev/null +++ b/include/filename.h @@ -0,0 +1,110 @@ +/* Basic filename support macros. + Copyright (C) 2001-2004, 2007-2020 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* From Paul Eggert and Jim Meyering. */ + +#ifndef _FILENAME_H +#define _FILENAME_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Filename support. + ISSLASH(C) tests whether C is a directory separator + character. + HAS_DEVICE(Filename) tests whether Filename contains a device + specification. + FILE_SYSTEM_PREFIX_LEN(Filename) length of the device specification + at the beginning of Filename, + index of the part consisting of + alternating components and slashes. + FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE + 1 when a non-empty device specification + can be followed by an empty or relative + part, + 0 when a non-empty device specification + must be followed by a slash, + 0 when device specification don't exist. + IS_ABSOLUTE_FILE_NAME(Filename) + tests whether Filename is independent of + any notion of "current directory". + IS_RELATIVE_FILE_NAME(Filename) + tests whether Filename may be concatenated + to a directory filename. + Note: On native Windows, OS/2, DOS, "c:" is neither an absolute nor a + relative file name! + IS_FILE_NAME_WITH_DIR(Filename) tests whether Filename contains a device + or directory specification. + */ +#if defined _WIN32 || defined __CYGWIN__ \ + || defined __EMX__ || defined __MSDOS__ || defined __DJGPP__ + /* Native Windows, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') + /* Internal macro: Tests whether a character is a drive letter. */ +# define _IS_DRIVE_LETTER(C) \ + (((C) >= 'A' && (C) <= 'Z') || ((C) >= 'a' && (C) <= 'z')) + /* Help the compiler optimizing it. This assumes ASCII. */ +# undef _IS_DRIVE_LETTER +# define _IS_DRIVE_LETTER(C) \ + (((unsigned int) (C) | ('a' - 'A')) - 'a' <= 'z' - 'a') +# define HAS_DEVICE(Filename) \ + (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':') +# define FILE_SYSTEM_PREFIX_LEN(Filename) (HAS_DEVICE (Filename) ? 2 : 0) +# ifdef __CYGWIN__ +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 +# else + /* On native Windows, OS/2, DOS, the system has the notion of a + "current directory" on each drive. */ +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 +# endif +# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE +# define IS_ABSOLUTE_FILE_NAME(Filename) \ + ISSLASH ((Filename)[FILE_SYSTEM_PREFIX_LEN (Filename)]) +# else +# define IS_ABSOLUTE_FILE_NAME(Filename) \ + (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename)) +# endif +# define IS_RELATIVE_FILE_NAME(Filename) \ + (! (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename))) +# define IS_FILE_NAME_WITH_DIR(Filename) \ + (strchr ((Filename), '/') != NULL || strchr ((Filename), '\\') != NULL \ + || HAS_DEVICE (Filename)) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define HAS_DEVICE(Filename) ((void) (Filename), 0) +# define FILE_SYSTEM_PREFIX_LEN(Filename) ((void) (Filename), 0) +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 +# define IS_ABSOLUTE_FILE_NAME(Filename) ISSLASH ((Filename)[0]) +# define IS_RELATIVE_FILE_NAME(Filename) (! ISSLASH ((Filename)[0])) +# define IS_FILE_NAME_WITH_DIR(Filename) (strchr ((Filename), '/') != NULL) +#endif + +/* Deprecated macros. For backward compatibility with old users of the + 'filename' module. */ +#define IS_ABSOLUTE_PATH IS_ABSOLUTE_FILE_NAME +#define IS_PATH_WITH_DIR IS_FILE_NAME_WITH_DIR + + +#ifdef __cplusplus +} +#endif + +#endif /* _FILENAME_H */ From patchwork Tue Dec 29 19:34:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1421240 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=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=UPtMu/pE; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (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 4D54Q2459kz9sVb for ; Wed, 30 Dec 2020 06:35:22 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 827E4388A43E; Tue, 29 Dec 2020 19:35:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 827E4388A43E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1609270508; bh=BRTobmsW2yTX1HG5dDOjq/RbHRadsEpcXdG/dendWt4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=UPtMu/pE/Aez+eQktmM6D+eaQb7dQNcn/rZvkhhSOI/Szn8M1lcWrL+ZgnRPJDBbT FD7UXjWKpa+lu6uK5IijhgOesR5wQtmljO5Ry6mTGTKpHRdP0qoIZxHq9O+AQnLo5N imVdOBchNRa2ewh7pu6qjxEyH7p+RIKnzgFiVOcs= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qv1-xf34.google.com (mail-qv1-xf34.google.com [IPv6:2607:f8b0:4864:20::f34]) by sourceware.org (Postfix) with ESMTPS id BB2CA388A426 for ; Tue, 29 Dec 2020 19:35:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org BB2CA388A426 Received: by mail-qv1-xf34.google.com with SMTP id d11so6779092qvo.11 for ; Tue, 29 Dec 2020 11:35:05 -0800 (PST) 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=BRTobmsW2yTX1HG5dDOjq/RbHRadsEpcXdG/dendWt4=; b=EdL1K7NfoJyccttUWcoWcbIhhY3F0pmF+J1mblUI2dwma6xCo01ax4jqH7lWIs/tLA o5NnUC+arOkVIrLEt8MTOa9gl8QDrfZqca345c6UUO48I4Uz5I3MAAd0oy7SYC7DBFpd EwmGuXGgssBGD0c9fhY1nPo5gvH0eMVXvdTN0hPVBHqsDWe6jviZkrk2+AuTWpBWShBh Qp18s1HvhoNNbrrgHXTaQ1QO+blPOyApgPyqz/akw1y5v0KMYtWXsiKLwkry6XW4vv+8 Dd1eyEd+U3awVaWGGo/j17Pq3bZEYdHbXMWcoIzqiwN0gSKMYCcTaDwnfNgcgQ9YRqb2 Re5g== X-Gm-Message-State: AOAM531xibS90KRJ+gKHzhKUlW2Pf8sCPIap499KQSl8rThlFa1zbPYi WVbw3zfQ6LS7LVo1mJ1QtwBVcKQ/JG94bg== X-Google-Smtp-Source: ABdhPJyw9A0WyRe3pNhD+9jDcn6ZS18XOUjIdK9egbgAgtboFpAXawLZp6p9CgyroywDy/BExB4Imw== X-Received: by 2002:a0c:efc9:: with SMTP id a9mr52921474qvt.31.1609270505075; Tue, 29 Dec 2020 11:35:05 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b14sm25383428qtx.36.2020.12.29.11.35.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Dec 2020 11:35:04 -0800 (PST) To: libc-alpha@sourceware.org, Paul Eggert Subject: [PATCH v3 3/6] malloc: Add scratch_buffer_dupfree Date: Tue, 29 Dec 2020 16:34:51 -0300 Message-Id: <20201229193454.34558-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201229193454.34558-1-adhemerval.zanella@linaro.org> References: <20201229193454.34558-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 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.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: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: bug-gnulib@gnu.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" It returns a copy of the buffer up to a defined size. It will be used on realpath sync with gnulib. --- include/scratch_buffer.h | 16 +++++++++++++ malloc/Makefile | 1 + malloc/Versions | 1 + malloc/scratch_buffer_dupfree.c | 41 +++++++++++++++++++++++++++++++++ malloc/tst-scratch_buffer.c | 26 +++++++++++++++++++-- 5 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 malloc/scratch_buffer_dupfree.c diff --git a/include/scratch_buffer.h b/include/scratch_buffer.h index c39da78629..48d651b41a 100644 --- a/include/scratch_buffer.h +++ b/include/scratch_buffer.h @@ -132,4 +132,20 @@ scratch_buffer_set_array_size (struct scratch_buffer *buffer, (buffer, nelem, size)); } +/* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block, + deallocating *BUFFER if it was heap-allocated. SIZE must be at + most *BUFFER's size. Return NULL (setting errno) on memory + exhaustion. */ +void *__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, + size_t size); +libc_hidden_proto (__libc_scratch_buffer_dupfree) + +/* Alias for __libc_scratch_dupfree. */ +static __always_inline void * +scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size) +{ + void *r = __libc_scratch_buffer_dupfree (buffer, size); + return __glibc_likely (r != NULL) ? r : NULL; +} + #endif /* _SCRATCH_BUFFER_H */ diff --git a/malloc/Makefile b/malloc/Makefile index 39ffaa7161..ef70b547f9 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -74,6 +74,7 @@ tests-exclude-mcheck = tst-mcheck tst-malloc-usable \ tests-mcheck = $(filter-out $(tests-exclude-mcheck),$(tests)) routines = malloc morecore mcheck mtrace obstack reallocarray \ + scratch_buffer_dupfree \ scratch_buffer_grow scratch_buffer_grow_preserve \ scratch_buffer_set_array_size \ dynarray_at_failure \ diff --git a/malloc/Versions b/malloc/Versions index 94c8ba8040..6693c46ee2 100644 --- a/malloc/Versions +++ b/malloc/Versions @@ -75,6 +75,7 @@ libc { __libc_thread_freeres; # struct scratch_buffer support + __libc_scratch_buffer_dupfree; __libc_scratch_buffer_grow; __libc_scratch_buffer_grow_preserve; __libc_scratch_buffer_set_array_size; diff --git a/malloc/scratch_buffer_dupfree.c b/malloc/scratch_buffer_dupfree.c new file mode 100644 index 0000000000..5561e99b0a --- /dev/null +++ b/malloc/scratch_buffer_dupfree.c @@ -0,0 +1,41 @@ +/* Variable-sized buffer with on-stack default allocation. + Copyright (C) 2020 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 + . */ + +#ifndef _LIBC +# include +#endif + +#include +#include + +void * +__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size) +{ + void *data = buffer->data; + if (data == buffer->__space.__c) + { + void *copy = malloc (size); + return copy != NULL ? memcpy (copy, data, size) : NULL; + } + else + { + void *copy = realloc (data, size); + return copy != NULL ? copy : data; + } +} +libc_hidden_def (__libc_scratch_buffer_dupfree) diff --git a/malloc/tst-scratch_buffer.c b/malloc/tst-scratch_buffer.c index ef5fb0a8eb..6008113174 100644 --- a/malloc/tst-scratch_buffer.c +++ b/malloc/tst-scratch_buffer.c @@ -16,7 +16,10 @@ License along with the GNU C Library; if not, see . */ +#include #include +#include +#include #include #include #include @@ -148,8 +151,27 @@ do_test (void) && array_size_must_fail (4, ((size_t)-1) / 4))) return 1; } + { + struct scratch_buffer buf; + scratch_buffer_init (&buf); + memset (buf.data, '@', buf.length); + + size_t sizes[] = { 16, buf.length, buf.length + 16 }; + for (int i = 0; i < array_length (sizes); i++) + { + /* The extra size is unitialized through realloc. */ + size_t l = sizes[i] > buf.length ? sizes[i] : buf.length; + void *r = scratch_buffer_dupfree (&buf, l); + void *c = xmalloc (l); + memset (c, '@', l); + TEST_COMPARE_BLOB (r, l, buf.data, l); + free (r); + free (c); + } + + scratch_buffer_free (&buf); + } return 0; } -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include From patchwork Tue Dec 29 19:34:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1421242 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=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=YwNZZFbh; dkim-atps=neutral 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 4D54QC1p14z9sVb for ; Wed, 30 Dec 2020 06:35:31 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9DA0C388A83D; Tue, 29 Dec 2020 19:35:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9DA0C388A83D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1609270511; bh=zel25Fe0JDQQ2TJ7iendLCaho/94u1JV9m/5HqFzAl8=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=YwNZZFbhRlcZQgOGMYUSIRB9jZFJ1RtCqbr0fOyAAs0OcDeA4vDFGD3OrBCDlvq0b 5FQFDJV9j3bvn7Yb70q7+CaQ3E0uJqSNPrs+DisJVgN7XqUjOSY/38GjoOPcnuNQ7T Ua+hdlcQz3DpVf1+cDDdcLZ/fLPrSZF/P7lJ3Kcg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by sourceware.org (Postfix) with ESMTPS id E4A9A388A412 for ; Tue, 29 Dec 2020 19:35:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E4A9A388A412 Received: by mail-qv1-xf35.google.com with SMTP id p5so6790757qvs.7 for ; Tue, 29 Dec 2020 11:35:07 -0800 (PST) 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=zel25Fe0JDQQ2TJ7iendLCaho/94u1JV9m/5HqFzAl8=; b=l7q9pQ5tkZfMD1xga1JAM3Ogct21HnY0XR8Njs2unbo/zybrUZE6A0KImpRu5nuBaF 7CNB69FGinqPdRahUeQgkVL1cbFYBCyhZ/ka9CrMHGUT7oWfVPFWFfF/e6jRtNPMCluL DivYTDFNHfPcL23z5VhYUFuvL5W0gYv1KL2JOYIbtLXwddKWp/BXRfwUZJzpyGeP3K76 qBqid6dQ5lko4WTga03aXn6SG0uHVo3KCq8xNMJRsE71bD1qSx/86sV8H9Hc3TCdoUCu lame4LALAyDp3C5xXhM/Y9BDBsroBR+VyrG8XXQB8b/cWWhScQGOxq86zE2DPVapogsw syQw== X-Gm-Message-State: AOAM531nwPwhwcp4znwmKofUlXy1IvmLRLc2uyXLIuObEz41xUhkJUo7 hs+L2lf/6WbdFF2bHPGs/RHknYYKkrS2mw== X-Google-Smtp-Source: ABdhPJyfXSa+qV8yp/nOnjcReQHIp3PjL94vIzxRupXAMNg4Jn1FaERRTzM+4xOjSH1KqtAAgJ/YUw== X-Received: by 2002:a05:6214:14ee:: with SMTP id k14mr52817440qvw.36.1609270506832; Tue, 29 Dec 2020 11:35:06 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b14sm25383428qtx.36.2020.12.29.11.35.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Dec 2020 11:35:06 -0800 (PST) To: libc-alpha@sourceware.org, Paul Eggert Subject: [PATCH v3 4/6] stdlib: Sync canonicalize with gnulib [BZ #10635] [BZ #26592] [BZ #26341] [BZ #24970] Date: Tue, 29 Dec 2020 16:34:52 -0300 Message-Id: <20201229193454.34558-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201229193454.34558-1-adhemerval.zanella@linaro.org> References: <20201229193454.34558-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 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.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: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: bug-gnulib@gnu.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" It sync with gnulib version b29d62dfa with the following change: diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c index 04fe95253f..c8f085b779 100644 --- a/stdlib/canonicalize.c +++ b/stdlib/canonicalize.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef _LIBC # include @@ -339,6 +340,11 @@ realpath_stk (const char *name, char *resolved, if (end_in_extra_buffer) end_idx = end - extra_buf; idx_t len = strlen (end); + if (INT_ADD_OVERFLOW (len, n)) + { + __set_errno (ENAMETOOLONG); + goto error_nomem; + } while (extra_buffer.length <= len + n) { if (!scratch_buffer_grow_preserve (&extra_buffer)) -- It is required to avoid stdlib/test-bz22786 regression, where it passes string larger than PTRDIFF_T as the input argument. Althought it uses a pointer larger than the one malloc would return (BZ#23741), it is still a semantic support for glibc and ENAMETOOLONG should be returned. The patch also fixes multiple realpath issues: - Portability fixes for errno clobbering on free (BZ#10635). The function does not call free directly anymore, although it might be done through scratch_buffer_free. The free errno clobbering is being tracked by BZ#17924. - Pointer arithmetic overflows in realpath (BZ#26592). - Realpath cyclically call __alloca(path_max) to consume too much stack space (BZ#26341). - Realpath mishandles EOVERFLOW; stat not needed anyway (BZ#24970). The check is done through faccessat now. Checked on x86_64-linux-gnu. --- stdlib/canonicalize.c | 547 +++++++++++++++++++--------- sysdeps/unix/sysv/linux/faccessat.c | 3 +- 2 files changed, 386 insertions(+), 164 deletions(-) diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c index 3fcb399a5d..c8f085b779 100644 --- a/stdlib/canonicalize.c +++ b/stdlib/canonicalize.c @@ -16,43 +16,200 @@ License along with the GNU C Library; if not, see . */ -#include +#ifndef _LIBC +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the name == NULL test below. */ +# define _GL_ARG_NONNULL(params) + +# define _GL_USE_STDLIB_ALLOC 1 +# include +#endif + +/* Specification. */ #include -#include -#include -#include -#include + #include +#include +#include +#include #include +#include +#include +#include #include -#include +#include +#include +#include +#include + +#ifdef _LIBC +# include +# define GCC_LINT 1 +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +#else +# define __canonicalize_file_name canonicalize_file_name +# define __realpath realpath +# include "pathmax.h" +# define __faccessat faccessat +# if defined _WIN32 && !defined __CYGWIN__ +# define __getcwd _getcwd +# elif HAVE_GETCWD +# if IN_RELOCWRAPPER + /* When building the relocatable program wrapper, use the system's getcwd + function, not the gnulib override, otherwise we would get a link error. + */ +# undef getcwd +# endif +# if defined VMS && !defined getcwd + /* We want the directory in Unix syntax, not in VMS syntax. + The gnulib override of 'getcwd' takes 2 arguments; the original VMS + 'getcwd' takes 3 arguments. */ +# define __getcwd(buf, max) getcwd (buf, max, 0) +# else +# define __getcwd getcwd +# endif +# else +# define __getcwd(buf, max) getwd (buf) +# endif +# define __mempcpy mempcpy +# define __pathconf pathconf +# define __rawmemchr rawmemchr +# define __readlink readlink +# define __stat stat +#endif -/* Return the canonical absolute name of file NAME. A canonical name - does not contain any `.', `..' components nor any repeated path - separators ('/') or symlinks. All path components must exist. If - RESOLVED is null, the result is malloc'd; otherwise, if the - canonical name is PATH_MAX chars or more, returns null with `errno' - set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, - returns the name in RESOLVED. If the name cannot be resolved and - RESOLVED is non-NULL, it contains the path of the first component - that cannot be resolved. If the path can be resolved, RESOLVED - holds the same value as the value returned. */ +/* Suppress bogus GCC -Wmaybe-uninitialized warnings. */ +#if defined GCC_LINT || defined lint +# define IF_LINT(Code) Code +#else +# define IF_LINT(Code) /* empty */ +#endif -char * -__realpath (const char *name, char *resolved) +#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT +# define DOUBLE_SLASH_IS_DISTINCT_ROOT false +#endif + +#if defined _LIBC || !FUNC_REALPATH_WORKS + +/* Return true if FILE's existence can be shown, false (setting errno) + otherwise. Follow symbolic links. */ +static bool +file_accessible (char const *file) +{ +# if defined _LIBC || HAVE_FACCESSAT + return __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS) == 0; +# else + struct stat st; + return __stat (file, &st) == 0 || errno == EOVERFLOW; +# endif +} + +/* True if concatenating END as a suffix to a file name means that the + code needs to check that the file name is that of a searchable + directory, since the canonicalize_filename_mode_stk code won't + check this later anyway when it checks an ordinary file name + component within END. END must either be empty, or start with a + slash. */ + +static bool _GL_ATTRIBUTE_PURE +suffix_requires_dir_check (char const *end) +{ + /* If END does not start with a slash, the suffix is OK. */ + while (ISSLASH (*end)) + { + /* Two or more slashes act like a single slash. */ + do + end++; + while (ISSLASH (*end)); + + switch (*end++) + { + default: return false; /* An ordinary file name component is OK. */ + case '\0': return true; /* Trailing "/" is trouble. */ + case '.': break; /* Possibly "." or "..". */ + } + /* Trailing "/.", or "/.." even if not trailing, is trouble. */ + if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1])))) + return true; + } + + return false; +} + +/* Append this to a file name to test whether it is a searchable directory. + On POSIX platforms "/" suffices, but "/./" is sometimes needed on + macOS 10.13 , and should also work on + platforms like AIX 7.2 that need at least "/.". */ + +#if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK +static char const dir_suffix[] = "/"; +#else +static char const dir_suffix[] = "/./"; +#endif + +/* Return true if DIR is a searchable dir, false (setting errno) otherwise. + DIREND points to the NUL byte at the end of the DIR string. + Store garbage into DIREND[0 .. strlen (dir_suffix)]. */ + +static bool +dir_check (char *dir, char *dirend) +{ + strcpy (dirend, dir_suffix); + return file_accessible (dir); +} + +static idx_t +get_path_max (void) +{ +# ifdef PATH_MAX + long int path_max = PATH_MAX; +# else + /* The caller invoked realpath with a null RESOLVED, even though + PATH_MAX is not defined as a constant. The glibc manual says + programs should not do this, and POSIX says the behavior is undefined. + Historically, glibc here used the result of pathconf, or 1024 if that + failed; stay consistent with this (dubious) historical practice. */ + int err = errno; + long int path_max = __pathconf ("/", _PC_PATH_MAX); + __set_errno (err); +# endif + return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX; +} + +/* Act like __realpath (see below), with an additional argument + rname_buf that can be used as temporary storage. + + If GCC_LINT is defined, do not inline this function with GCC 10.1 + and later, to avoid creating a pointer to the stack that GCC + -Wreturn-local-addr incorrectly complains about. See: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644 + Although the noinline attribute can hurt performance a bit, no better way + to pacify GCC is known; even an explicit #pragma does not pacify GCC. + When the GCC bug is fixed this workaround should be limited to the + broken GCC versions. */ +#if __GNUC_PREREQ (10, 1) +# if defined GCC_LINT || defined lint +__attribute__ ((__noinline__)) +# elif __OPTIMIZE__ && !__NO_INLINE__ +# define GCC_BOGUS_WRETURN_LOCAL_ADDR +# endif +#endif +static char * +realpath_stk (const char *name, char *resolved, + struct scratch_buffer *rname_buf) { - char *rpath, *dest, *extra_buf = NULL; - const char *start, *end, *rpath_limit; - long int path_max; + char *dest; + char const *start; + char const *end; int num_links = 0; if (name == NULL) { /* As per Single Unix Specification V2 we must return an error if - either parameter is a null pointer. We extend this to allow - the RESOLVED parameter to be NULL in case the we are expected to - allocate the room for the return value. */ + either parameter is a null pointer. We extend this to allow + the RESOLVED parameter to be NULL in case the we are expected to + allocate the room for the return value. */ __set_errno (EINVAL); return NULL; } @@ -60,166 +217,230 @@ __realpath (const char *name, char *resolved) if (name[0] == '\0') { /* As per Single Unix Specification V2 we must return an error if - the name argument points to an empty string. */ + the name argument points to an empty string. */ __set_errno (ENOENT); return NULL; } -#ifdef PATH_MAX - path_max = PATH_MAX; -#else - path_max = __pathconf (name, _PC_PATH_MAX); - if (path_max <= 0) - path_max = 1024; -#endif + struct scratch_buffer extra_buffer, link_buffer; + scratch_buffer_init (&extra_buffer); + scratch_buffer_init (&link_buffer); + scratch_buffer_init (rname_buf); + char *rname_on_stack = rname_buf->data; + char *rname = rname_on_stack; + bool end_in_extra_buffer = false; + bool failed = true; - if (resolved == NULL) - { - rpath = malloc (path_max); - if (rpath == NULL) - return NULL; - } - else - rpath = resolved; - rpath_limit = rpath + path_max; + /* This is always zero for Posix hosts, but can be 2 for MS-Windows + and MS-DOS X:/foo/bar file names. */ + idx_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); - if (name[0] != '/') + if (!IS_ABSOLUTE_FILE_NAME (name)) { - if (!__getcwd (rpath, path_max)) - { - rpath[0] = '\0'; - goto error; - } - dest = __rawmemchr (rpath, '\0'); + while (!__getcwd (rname, rname_buf->length)) + { + if (errno != ERANGE) + { + dest = rname; + goto error; + } + if (!scratch_buffer_grow (rname_buf)) + goto error_nomem; + rname = rname_buf->data; + } + dest = __rawmemchr (rname, '\0'); + start = name; + prefix_len = FILE_SYSTEM_PREFIX_LEN (rname); } else { - rpath[0] = '/'; - dest = rpath + 1; + dest = __mempcpy (rname, name, prefix_len); + *dest++ = '/'; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT) + { + if (prefix_len == 0 /* implies ISSLASH (name[0]) */ + && ISSLASH (name[1]) && !ISSLASH (name[2])) + *dest++ = '/'; + *dest = '\0'; + } + start = name + prefix_len; } - for (start = end = name; *start; start = end) + for ( ; *start; start = end) { - struct stat64 st; - int n; - - /* Skip sequence of multiple path-separators. */ - while (*start == '/') - ++start; - - /* Find end of path component. */ - for (end = start; *end && *end != '/'; ++end) - /* Nothing. */; - - if (end - start == 0) - break; - else if (end - start == 1 && start[0] == '.') - /* nothing */; - else if (end - start == 2 && start[0] == '.' && start[1] == '.') - { - /* Back up to previous component, ignore if at root already. */ - if (dest > rpath + 1) - while ((--dest)[-1] != '/'); - } + /* Skip sequence of multiple file name separators. */ + while (ISSLASH (*start)) + ++start; + + /* Find end of component. */ + for (end = start; *end && !ISSLASH (*end); ++end) + /* Nothing. */; + + /* Length of this file name component; it can be zero if a file + name ends in '/'. */ + idx_t startlen = end - start; + + if (startlen == 0) + break; + else if (startlen == 1 && start[0] == '.') + /* nothing */; + else if (startlen == 2 && start[0] == '.' && start[1] == '.') + { + /* Back up to previous component, ignore if at root already. */ + if (dest > rname + prefix_len + 1) + for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest) + continue; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT + && dest == rname + 1 && !prefix_len + && ISSLASH (*dest) && !ISSLASH (dest[1])) + dest++; + } else - { - size_t new_size; - - if (dest[-1] != '/') - *dest++ = '/'; - - if (dest + (end - start) >= rpath_limit) - { - ptrdiff_t dest_offset = dest - rpath; - char *new_rpath; - - if (resolved) - { - __set_errno (ENAMETOOLONG); - if (dest > rpath + 1) - dest--; - *dest = '\0'; - goto error; - } - new_size = rpath_limit - rpath; - if (end - start + 1 > path_max) - new_size += end - start + 1; - else - new_size += path_max; - new_rpath = (char *) realloc (rpath, new_size); - if (new_rpath == NULL) - goto error; - rpath = new_rpath; - rpath_limit = rpath + new_size; - - dest = rpath + dest_offset; - } - - dest = __mempcpy (dest, start, end - start); - *dest = '\0'; - - if (__lstat64 (rpath, &st) < 0) - goto error; - - if (S_ISLNK (st.st_mode)) - { - char *buf = __alloca (path_max); - size_t len; - - if (++num_links > __eloop_threshold ()) - { - __set_errno (ELOOP); - goto error; - } - - n = __readlink (rpath, buf, path_max - 1); - if (n < 0) - goto error; - buf[n] = '\0'; - - if (!extra_buf) - extra_buf = __alloca (path_max); - - len = strlen (end); - if (path_max - n <= len) - { - __set_errno (ENAMETOOLONG); - goto error; - } - - /* Careful here, end may be a pointer into extra_buf... */ - memmove (&extra_buf[n], end, len + 1); - name = end = memcpy (extra_buf, buf, n); - - if (buf[0] == '/') - dest = rpath + 1; /* It's an absolute symlink */ - else - /* Back up to previous component, ignore if at root already: */ - if (dest > rpath + 1) - while ((--dest)[-1] != '/'); - } - else if (!S_ISDIR (st.st_mode) && *end != '\0') - { - __set_errno (ENOTDIR); - goto error; - } - } + { + if (!ISSLASH (dest[-1])) + *dest++ = '/'; + + while (rname + rname_buf->length - dest + < startlen + sizeof dir_suffix) + { + idx_t dest_offset = dest - rname; + if (!scratch_buffer_grow_preserve (rname_buf)) + goto error_nomem; + rname = rname_buf->data; + dest = rname + dest_offset; + } + + dest = __mempcpy (dest, start, startlen); + *dest = '\0'; + + char *buf; + ssize_t n; + while (true) + { + buf = link_buffer.data; + idx_t bufsize = link_buffer.length; + n = __readlink (rname, buf, bufsize - 1); + if (n < bufsize - 1) + break; + if (!scratch_buffer_grow (&link_buffer)) + goto error_nomem; + } + if (0 <= n) + { + if (++num_links > __eloop_threshold ()) + { + __set_errno (ELOOP); + goto error; + } + + buf[n] = '\0'; + + char *extra_buf = extra_buffer.data; + idx_t end_idx IF_LINT (= 0); + if (end_in_extra_buffer) + end_idx = end - extra_buf; + idx_t len = strlen (end); + if (INT_ADD_OVERFLOW (len, n)) + { + __set_errno (ENAMETOOLONG); + goto error_nomem; + } + while (extra_buffer.length <= len + n) + { + if (!scratch_buffer_grow_preserve (&extra_buffer)) + goto error_nomem; + extra_buf = extra_buffer.data; + } + if (end_in_extra_buffer) + end = extra_buf + end_idx; + + /* Careful here, end may be a pointer into extra_buf... */ + memmove (&extra_buf[n], end, len + 1); + name = end = memcpy (extra_buf, buf, n); + end_in_extra_buffer = true; + + if (IS_ABSOLUTE_FILE_NAME (buf)) + { + idx_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf); + + dest = __mempcpy (rname, buf, pfxlen); + *dest++ = '/'; /* It's an absolute symlink */ + if (DOUBLE_SLASH_IS_DISTINCT_ROOT) + { + if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen) + *dest++ = '/'; + *dest = '\0'; + } + /* Install the new prefix to be in effect hereafter. */ + prefix_len = pfxlen; + } + else + { + /* Back up to previous component, ignore if at root + already: */ + if (dest > rname + prefix_len + 1) + for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest) + continue; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 + && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len) + dest++; + } + } + else if (! (suffix_requires_dir_check (end) + ? dir_check (rname, dest) + : errno == EINVAL)) + goto error; + } } - if (dest > rpath + 1 && dest[-1] == '/') + if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1])) --dest; - *dest = '\0'; - - assert (resolved == NULL || resolved == rpath); - return rpath; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len + && ISSLASH (*dest) && !ISSLASH (dest[1])) + dest++; + failed = false; error: - assert (resolved == NULL || resolved == rpath); - if (resolved == NULL) - free (rpath); - return NULL; + *dest++ = '\0'; + if (resolved != NULL && dest - rname <= get_path_max ()) + rname = strcpy (resolved, rname); + +error_nomem: + scratch_buffer_free (&extra_buffer); + scratch_buffer_free (&link_buffer); + + if (failed || rname == resolved) + { + scratch_buffer_free (rname_buf); + return failed ? NULL : resolved; + } + + return scratch_buffer_dupfree (rname_buf, dest - rname); +} + +/* Return the canonical absolute name of file NAME. A canonical name + does not contain any ".", ".." components nor any repeated file name + separators ('/') or symlinks. All file name components must exist. If + RESOLVED is null, the result is malloc'd; otherwise, if the + canonical name is PATH_MAX chars or more, returns null with 'errno' + set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, + returns the name in RESOLVED. If the name cannot be resolved and + RESOLVED is non-NULL, it contains the name of the first component + that cannot be resolved. If the name can be resolved, RESOLVED + holds the same value as the value returned. */ + +char * +__realpath (const char *name, char *resolved) +{ + #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR + #warning "GCC might issue a bogus -Wreturn-local-addr warning here." + #warning "See ." + #endif + struct scratch_buffer rname_buffer; + return realpath_stk (name, resolved, &rname_buffer); } libc_hidden_def (__realpath) versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); +#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */ #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3) diff --git a/sysdeps/unix/sysv/linux/faccessat.c b/sysdeps/unix/sysv/linux/faccessat.c index 5d078371b5..5bb1051c06 100644 --- a/sysdeps/unix/sysv/linux/faccessat.c +++ b/sysdeps/unix/sysv/linux/faccessat.c @@ -24,7 +24,7 @@ int -faccessat (int fd, const char *file, int mode, int flag) +__faccessat (int fd, const char *file, int mode, int flag) { int ret = INLINE_SYSCALL_CALL (faccessat2, fd, file, mode, flag); #if __ASSUME_FACCESSAT2 @@ -73,3 +73,4 @@ faccessat (int fd, const char *file, int mode, int flag) return INLINE_SYSCALL_ERROR_RETURN_VALUE (EACCES); #endif /* !__ASSUME_FACCESSAT2 */ } +weak_alias (__faccessat, faccessat) From patchwork Tue Dec 29 19:34:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1421241 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=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=gH7Cl9zw; dkim-atps=neutral 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 4D54Q66Z8tz9sVb for ; Wed, 30 Dec 2020 06:35:26 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 174BB388A838; Tue, 29 Dec 2020 19:35:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 174BB388A838 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1609270511; bh=xE3V2L7OAErV6E4tfNKE9TTze5DOJ7rgCTaFC8cxOWY=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=gH7Cl9zw8T7an8yiFT/6KWJ/QODFtiFKjpY4DkQs3uewYaSbs5hDBK/TVqPVvTuui eDo3kmFSdkspy7n3s5cYXhFdSEPOA0z7Lscbw4QMbzIUo5cuhBfB7LOFmzBOoEtbId v+IxfkBYCEFUOOvXWMRIsDweeMhuNYTeksww44+k= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x72f.google.com (mail-qk1-x72f.google.com [IPv6:2607:f8b0:4864:20::72f]) by sourceware.org (Postfix) with ESMTPS id 14555388A437 for ; Tue, 29 Dec 2020 19:35:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 14555388A437 Received: by mail-qk1-x72f.google.com with SMTP id 143so12211774qke.10 for ; Tue, 29 Dec 2020 11:35:09 -0800 (PST) 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=xE3V2L7OAErV6E4tfNKE9TTze5DOJ7rgCTaFC8cxOWY=; b=K2WTBGTXKfwLsxE+RHMRsuZhCJ3PuaRtPFrl5PoE9lZiCPTTVNAKGIAXgc1RHH3M9/ liwuhwE0vySJCnAtVUDwNvBYUyPm87MyEGAUrtepnAUh/7ybW7EL8vNq6N+3sVai+9o7 XvFvvAGwHBTbIlcG1bDlFjxB6X6Ae8jsJa/ZY4SWL69yHqotL4h7EiSl+wmhXIC5aHI5 uB8k+vQpwfwH9A1F3G7/g70x+4eu6pf8huk+qhZn2LS5DkcIP3TlwVNXMP5urYatWcQO TPeUrNvpvQ5WeuhMnLES05KaVXwCfA/IYtBiuDZtU9bksgA37qcxe/nZhlDVL1AAMM+/ yheQ== X-Gm-Message-State: AOAM532PIuGWvEM/Ug6MnkeBljB+Tlud0l3T6AaCTbiI0Td41hiQRruh /QovTZfq4MgY9Nh1yqBZ2j2ZEUfsFlEYEw== X-Google-Smtp-Source: ABdhPJwt8pyb/NgnG5RL1tGfNfNpb7cBxHZHZcIZhAfZoOTyec3FhqkaDIQK2Yn/knW3bv+pVKFhcA== X-Received: by 2002:a37:6541:: with SMTP id z62mr49845495qkb.270.1609270508512; Tue, 29 Dec 2020 11:35:08 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b14sm25383428qtx.36.2020.12.29.11.35.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Dec 2020 11:35:08 -0800 (PST) To: libc-alpha@sourceware.org, Paul Eggert Subject: [PATCH v3 5/6] support: Add support_small_thread_stack_size Date: Tue, 29 Dec 2020 16:34:53 -0300 Message-Id: <20201229193454.34558-6-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201229193454.34558-1-adhemerval.zanella@linaro.org> References: <20201229193454.34558-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, 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: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: bug-gnulib@gnu.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" It returns the minimum stack size large enough to cover most internal glibc stack usage. --- support/support_set_small_thread_stack_size.c | 12 +++++++++--- support/xthread.h | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/support/support_set_small_thread_stack_size.c b/support/support_set_small_thread_stack_size.c index 69d66e97db..74a0e38a72 100644 --- a/support/support_set_small_thread_stack_size.c +++ b/support/support_set_small_thread_stack_size.c @@ -20,8 +20,8 @@ #include #include -void -support_set_small_thread_stack_size (pthread_attr_t *attr) +size_t +support_small_thread_stack_size (void) { /* Some architectures have too small values for PTHREAD_STACK_MIN which cannot be used for creating threads. Ensure that the stack @@ -31,5 +31,11 @@ support_set_small_thread_stack_size (pthread_attr_t *attr) if (stack_size < PTHREAD_STACK_MIN) stack_size = PTHREAD_STACK_MIN; #endif - xpthread_attr_setstacksize (attr, stack_size); + return stack_size; +} + +void +support_set_small_thread_stack_size (pthread_attr_t *attr) +{ + xpthread_attr_setstacksize (attr, support_small_thread_stack_size ()); } diff --git a/support/xthread.h b/support/xthread.h index 05f8d4a7d9..9aeee80032 100644 --- a/support/xthread.h +++ b/support/xthread.h @@ -75,6 +75,8 @@ void xpthread_attr_setstacksize (pthread_attr_t *attr, void xpthread_attr_setguardsize (pthread_attr_t *attr, size_t guardsize); +/* Return the stack size used on support_set_small_thread_stack_size. */ +size_t support_small_thread_stack_size (void); /* Set the stack size in ATTR to a small value, but still large enough to cover most internal glibc stack usage. */ void support_set_small_thread_stack_size (pthread_attr_t *attr); From patchwork Tue Dec 29 19:34:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1421243 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=pass (p=none dis=none) header.from=sourceware.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=vCwhvyii; dkim-atps=neutral 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 4D54QJ15BLz9sVb for ; Wed, 30 Dec 2020 06:35:36 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A3365388A83F; Tue, 29 Dec 2020 19:35:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A3365388A83F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1609270513; bh=oxlCNy330HAbW5MCqV+B28MDobXK5dKQ5vlfBjblcOg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=vCwhvyiiSf3JGnMQ/atajqAZ45OKQCV2/FSZuUALpa7voTRQzrQOVhgilI9X6XjP9 BXljVwXHcPkjIOLCALoay6Wc9j/6TpMPRdE6+flMjS7v5weSexqqKFwfHNWJjDFKhP FD0hnH4jjmhY5nCbUhoTbSen1sJYxOQOnea4hwio= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x72d.google.com (mail-qk1-x72d.google.com [IPv6:2607:f8b0:4864:20::72d]) by sourceware.org (Postfix) with ESMTPS id C2CC1388A412 for ; Tue, 29 Dec 2020 19:35:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C2CC1388A412 Received: by mail-qk1-x72d.google.com with SMTP id v126so12196344qkd.11 for ; Tue, 29 Dec 2020 11:35:10 -0800 (PST) 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=oxlCNy330HAbW5MCqV+B28MDobXK5dKQ5vlfBjblcOg=; b=TpYwnQX4vrG4SSImRspV23MUkmHp+zMku/W/ho9q0st8YFLrIFK0xHin6wV0M9sI5W uXkmz4hyKIJ2Kd9mD1AOxyu6JON/Log/2GvSAaKOOwbDty0YFvzGgTriKTAJU1aXmdNj yKuLxa2I+CvY7AO+I0veyYtqPzsS4X1SiHJgle2hBC089jXkWeMdTJ+S/dIyjR4gMrtb CK1Ldzkaob4tiaGi83+OTv4TZ/M9nsBCsmCmMkYB+VKinUkPGKfpSIAj8Bs1V+iiJk9o i5yAPxDNA3aftAr+4KTlgHIYNQkIUOgkV/AN3cBgJXTCkJiy7HwP42N5LVFy8GydN7da 5B+A== X-Gm-Message-State: AOAM532aKzuIB24GxVNd7nO20yJNpWWDKzaEA+1XGZ6xqjfSz4ngGyEN FkDjL6v0kPgn8rL+ks8bIpI1pXr3XbedhA== X-Google-Smtp-Source: ABdhPJxqLCWrLn1sp2I3ywFA34B0ux0XaRaCVRzIqdtrgTIdWbzuIZxZ+h813Ltacr1MRCNzwk61BQ== X-Received: by 2002:a37:a707:: with SMTP id q7mr52581179qke.284.1609270510179; Tue, 29 Dec 2020 11:35:10 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b14sm25383428qtx.36.2020.12.29.11.35.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Dec 2020 11:35:09 -0800 (PST) To: libc-alpha@sourceware.org, Paul Eggert Subject: [PATCH v3 6/6] stdlib: Add testcase fro BZ #26241 Date: Tue, 29 Dec 2020 16:34:54 -0300 Message-Id: <20201229193454.34558-7-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201229193454.34558-1-adhemerval.zanella@linaro.org> References: <20201229193454.34558-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, 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: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: bug-gnulib@gnu.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" Old implementation of realpath allocates a PATH_MAX using alloca for each symlink in the path, leading to MAXSYMLINKS times PATH_MAX maximum stack usage. The test create a symlink with __eloop_threshold() loops and creates a thread with minimum stack size (obtained through support_small_stack_thread_attribute). The thread issues a stack allocations that fill the thread allocated stack minus some slack plus and the realpath usage (which assumes a bounded stack usage). If realpath uses more than aboud 2 * PATH_MAX plus some slack it trigger a stackoverflow. Checked on x86_64-linux-gnu and i686-linux-gnu. --- stdlib/Makefile | 3 +- stdlib/tst-canon-bz26341.c | 99 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 stdlib/tst-canon-bz26341.c diff --git a/stdlib/Makefile b/stdlib/Makefile index 29b7cd7071..6518d8993b 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -86,7 +86,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ tst-makecontext-align test-bz22786 tst-strtod-nan-sign \ tst-swapcontext1 tst-setcontext4 tst-setcontext5 \ tst-setcontext6 tst-setcontext7 tst-setcontext8 \ - tst-setcontext9 tst-bz20544 + tst-setcontext9 tst-bz20544 tst-canon-bz26341 tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ tst-tls-atexit tst-tls-atexit-nodelete @@ -101,6 +101,7 @@ LDLIBS-test-atexit-race = $(shared-thread-library) LDLIBS-test-at_quick_exit-race = $(shared-thread-library) LDLIBS-test-cxa_atexit-race = $(shared-thread-library) LDLIBS-test-on_exit-race = $(shared-thread-library) +LDLIBS-tst-canon-bz26341 = $(shared-thread-library) LDLIBS-test-dlclose-exit-race = $(shared-thread-library) $(libdl) LDFLAGS-test-dlclose-exit-race = $(LDFLAGS-rdynamic) diff --git a/stdlib/tst-canon-bz26341.c b/stdlib/tst-canon-bz26341.c new file mode 100644 index 0000000000..e0426ab306 --- /dev/null +++ b/stdlib/tst-canon-bz26341.c @@ -0,0 +1,99 @@ +/* Check if realpath does not consume extra stack space based on symlink + existance in the path (BZ #26341) + Copyright (C) 2020 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 + +#define __sysconf sysconf +#include +#include +#include +#include +#include +#include + +static char *filename; +static size_t filenamelen; +static char *linkname; + +#ifndef PATH_MAX +# define PATH_MAX 1024 +#endif + +static void +create_link (void) +{ + int fd = create_temp_file ("tst-canon-bz26341", &filename); + TEST_VERIFY_EXIT (fd != -1); + xclose (fd); + + char *prevlink = filename; + int maxlinks = __eloop_threshold (); + for (int i = 0; i < maxlinks; i++) + { + linkname = xasprintf ("%s%d", filename, i); + xsymlink (prevlink, linkname); + add_temp_file (linkname); + prevlink = linkname; + } + + filenamelen = strlen (filename); +} + +static void * +do_realpath (void *arg) +{ + /* Old implementation of realpath allocates a PATH_MAX using alloca + for each symlink in the path, leading to MAXSYMLINKS times PATH_MAX + maximum stack usage. + This stack allocations tries fill the thread allocated stack minus + both the resolved path (plus some slack) and the realpath (plus some + slack). + If realpath uses more than 2 * PATH_MAX plus some slack it will trigger + a stackoverflow. */ + + const size_t realpath_usage = 2 * PATH_MAX + 1024; + const size_t thread_usage = 1 * PATH_MAX + 1024; + size_t stack_size = support_small_thread_stack_size () + - realpath_usage - thread_usage; + char stack[stack_size]; + char *resolved = stack + stack_size - thread_usage + 1024; + + char *p = realpath (linkname, resolved); + TEST_VERIFY (p != NULL); + TEST_COMPARE_BLOB (resolved, filenamelen, filename, filenamelen); + + return NULL; +} + +static int +do_test (void) +{ + create_link (); + + pthread_t th = xpthread_create (support_small_stack_thread_attribute (), + do_realpath, NULL); + xpthread_join (th); + + return 0; +} + +#include