From patchwork Tue Apr 30 19:25:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1929813 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=U4chFoQ0; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=patchwork.ozlabs.org) Received: from server2.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 ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VTVjT5H7Tz23jG for ; Wed, 1 May 2024 05:33:17 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E07C5385842C for ; Tue, 30 Apr 2024 19:33:15 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x431.google.com (mail-pf1-x431.google.com [IPv6:2607:f8b0:4864:20::431]) by sourceware.org (Postfix) with ESMTPS id 287073858427 for ; Tue, 30 Apr 2024 19:32:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 287073858427 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 287073858427 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::431 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714505576; cv=none; b=uMdbWuACYVkp5hvnTN4QGYPqT+iOyZlM99COQ85KU5zM6e+JbsAWqN4lLkP0bv24yS4yAK5IRPgrojr+QbyoOkaepkO1simXiR7HPRTg+Nme1jVnw/Sza4ueEKX7HVlv4B/9RfppeZCI2rqYNb5BTESajTljCA4RbdBlmz2gV5Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714505576; c=relaxed/simple; bh=5tJ9lLFbyGsFg0h4d92IE+LhoPMx9PlOww2vm4CwJb8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=elWAPkIXpC8iRL061un4plvHGkXYZJaa0EHsWZIh+vzb6z4hpYdLuvyuxTqE1/YFPbSgXk3Iq+FeLj45Eo6feVT/sJT8CXPt7nArLgnUi+JjSxXEFXc0ziAmO6HChJBY0wygHZFv6ZLEimqzClT+bSm+d10MCGOf0ato2QfrQuk= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pf1-x431.google.com with SMTP id d2e1a72fcca58-6ed112c64beso5708478b3a.1 for ; Tue, 30 Apr 2024 12:32:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1714505572; x=1715110372; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TfH54N6gv6DErfWhfWw5ApNvj4CNjG8sOUy91PWaFGU=; b=U4chFoQ07ksIFpTWgU5U0kEtJ0n5adRKE1LdBvMG0O9ac1ASB6UEUrTf1Iv6EKmgRq BbJYftWdFhycrsgPrgvuvZqhdKRqgRo3jssGpoIsR2lK3B+j9h5C2lHyaY2ozqCRNeGn pBu/NUklwRMpAIADuzoJQoJYGgWbBWVwRRydmrooA8NE7Z7JtVzHELzL1l8Pf6wWb/Mv aZ6QJWHoWoBSEu3RNVBFBkPQo00chWdV/kWWM+rdnVX4rdfHEmURxe63DLg6Sq1Ad6GI 5ToCLjRVfSUg8WgTKQMYO7kTKNl7jo2S3nefcGsFM6qwxlmbPDAAuBJ+Qf8q9Sj7PnAT PdWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714505572; x=1715110372; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TfH54N6gv6DErfWhfWw5ApNvj4CNjG8sOUy91PWaFGU=; b=NNFAcwXizn0IuRKpVoDTJsZasZHxRuey9l9LDkwvLI+zZgy1iQBaVeNKAvEUyh5x26 LQZ/6cpEEacQlzxqnFMMa161WdGpXMDoMrqw2C1NJGq4fA8NznqA9Pwb7uMf+xu5I2FF 7BYi1VlqpuyWjCCgVeyjJOgzjmn9laeiMhJ18Y45lPecbz7R66de7jMGplAGFTZDCNHX 9KNhT1DIPGmcCPGNHa9DXiQDPUc2ApzCPiAJ1QkO/rDswxuRU/yyqpXTOiLYCfLdFkNw uzLxiJnl1V1ryxDn9rpHLqLkUzErX6iHn5U1qASoqxCJ6cpjoHGXHamgR6FPF6nr+VlJ yYYg== X-Gm-Message-State: AOJu0Yxy3Ju7x5vP+HQMEO7w5woCKNQrRG7MMZA8TNTHi63zyx/+BB4B 443LEXfDQWVSwEScCG05obkddo4FRJrlDEuKSmkzHxPRu56S1yjgVBsnjrBX7MdSGxojSq+/5Yd F X-Google-Smtp-Source: AGHT+IFE+ksiEo9WQ7PnA1U9pBLTo66eE4K9ZRf44VTAq2MpSlGQzOiu+Nqp3+HS2919wjS+0d/MDw== X-Received: by 2002:a05:6a20:6a12:b0:1af:35da:16 with SMTP id p18-20020a056a206a1200b001af35da0016mr906954pzk.52.1714505572159; Tue, 30 Apr 2024 12:32:52 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:e3c5:c9b5:f382:64ea:c32b]) by smtp.gmail.com with ESMTPSA id gr6-20020a056a004d0600b006ed1ea5219csm21449143pfb.130.2024.04.30.12.32.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Apr 2024 12:32:51 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Joe Simmons-Talbott , Siddhesh Poyarekar , Yuto Maeda Subject: [PATCH 1/4] elf: Only process multiple tunable once (BZ 31686) Date: Tue, 30 Apr 2024 16:25:02 -0300 Message-ID: <20240430192739.1032549-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240430192739.1032549-1-adhemerval.zanella@linaro.org> References: <20240430192739.1032549-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 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=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org The parse_tunables_string is a tunable entry on the 'tunable_list' list to be set later without checking if the entry is already present. If leads to a stack overflow if the tunable is set multiple times, for instance: GLIBC_TUNABLES=glibc.malloc.check=2:... (repeat over the number of total support for different tunable). Instead, use the index of the tunable list to get the expected tunable entry. Since now the initial list is zero-initialized, the compiler might emit an extra memset and this requires some minor adjustment on some ports. Checked on x86_64-linux-gnu and aarch64-linux-gnu. Reported-by: Yuto Maeda --- elf/dl-tunables.c | 30 ++++++----- elf/tst-tunables.c | 59 +++++++++++++++++++++- sysdeps/aarch64/multiarch/memset_generic.S | 4 ++ sysdeps/sparc/sparc64/rtld-memset.c | 3 ++ 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c index d3ccd2ecd4..1db80e0f92 100644 --- a/elf/dl-tunables.c +++ b/elf/dl-tunables.c @@ -32,6 +32,7 @@ #include #include #include +#include #define TUNABLES_INTERNAL 1 #include "dl-tunables.h" @@ -221,8 +222,7 @@ parse_tunables_string (const char *valstring, struct tunable_toset_t *tunables) if (tunable_is_name (cur->name, name)) { - tunables[ntunables++] = - (struct tunable_toset_t) { cur, value, p - value }; + tunables[i] = (struct tunable_toset_t) { cur, value, p - value }; /* Ignore tunables if enable_secure is set */ if (tunable_is_name ("glibc.rtld.enable_secure", name)) @@ -245,23 +245,27 @@ parse_tunables_string (const char *valstring, struct tunable_toset_t *tunables) static void parse_tunables (const char *valstring) { - struct tunable_toset_t tunables[tunables_list_size]; - int ntunables = parse_tunables_string (valstring, tunables); - if (ntunables == -1) + struct tunable_toset_t tunables[tunables_list_size] = { 0 }; + if (parse_tunables_string (valstring, tunables) == -1) { _dl_error_printf ( "WARNING: ld.so: invalid GLIBC_TUNABLES `%s': ignored.\n", valstring); return; } - for (int i = 0; i < ntunables; i++) - if (!tunable_initialize (tunables[i].t, tunables[i].value, - tunables[i].len)) - _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' " - "for option `%s': ignored.\n", - (int) tunables[i].len, - tunables[i].value, - tunables[i].t->name); + for (int i = 0; i < tunables_list_size; i++) + { + if (tunables[i].t == NULL) + continue; + + if (!tunable_initialize (tunables[i].t, tunables[i].value, + tunables[i].len)) + _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' " + "for option `%s': ignored.\n", + (int) tunables[i].len, + tunables[i].value, + tunables[i].t->name); + } } /* Initialize the tunables list from the environment. For now we only use the diff --git a/elf/tst-tunables.c b/elf/tst-tunables.c index 095b5c81d9..ce5f62f777 100644 --- a/elf/tst-tunables.c +++ b/elf/tst-tunables.c @@ -17,6 +17,7 @@ . */ #include +#define TUNABLES_INTERNAL 1 #include #include #include @@ -24,12 +25,13 @@ #include #include #include +#include static int restart; #define CMDLINE_OPTIONS \ { "restart", no_argument, &restart, 1 }, -static const struct test_t +static struct test_t { const char *name; const char *value; @@ -284,6 +286,29 @@ static const struct test_t 0, 0, }, + /* Also check for repeated tunables with a count larger than the total number + of tunables. */ + { + "GLIBC_TUNABLES", + NULL, + 2, + 0, + 0, + }, + { + "GLIBC_TUNABLES", + NULL, + 1, + 0, + 0, + }, + { + "GLIBC_TUNABLES", + NULL, + 0, + 0, + 0, + }, }; static int @@ -316,6 +341,7 @@ do_test (int argc, char *argv[]) char nteststr[INT_BUFSIZE_BOUND (int)]; + char *spargv[10]; { int i = 0; @@ -327,6 +353,37 @@ do_test (int argc, char *argv[]) spargv[i] = NULL; } + /* Create a tunable line with the duplicate values with a total number + larger than the different number of tunables. */ + { + enum { tunables_list_size = array_length (tunable_list) }; + const char *value = ""; + for (int i = 0; i < tunables_list_size; i++) + value = xasprintf ("%sglibc.malloc.check=2%c", + value, + i == (tunables_list_size - 1) ? '\0' : ':'); + tests[33].value = value; + } + /* Same as before, but the last tunable vallues is differen than the + rest. */ + { + enum { tunables_list_size = array_length (tunable_list) }; + const char *value = ""; + for (int i = 0; i < tunables_list_size - 1; i++) + value = xasprintf ("%sglibc.malloc.check=2:", value); + value = xasprintf ("%sglibc.malloc.check=1", value); + tests[34].value = value; + } + /* Same as before, but with an invalid last entry. */ + { + enum { tunables_list_size = array_length (tunable_list) }; + const char *value = ""; + for (int i = 0; i < tunables_list_size - 1; i++) + value = xasprintf ("%sglibc.malloc.check=2:", value); + value = xasprintf ("%sglibc.malloc.check=1=1", value); + tests[35].value = value; + } + for (int i = 0; i < array_length (tests); i++) { snprintf (nteststr, sizeof nteststr, "%d", i); diff --git a/sysdeps/aarch64/multiarch/memset_generic.S b/sysdeps/aarch64/multiarch/memset_generic.S index 81748bdbce..e125a5ed85 100644 --- a/sysdeps/aarch64/multiarch/memset_generic.S +++ b/sysdeps/aarch64/multiarch/memset_generic.S @@ -33,3 +33,7 @@ #endif #include <../memset.S> + +#if IS_IN (rtld) +strong_alias (memset, __memset_generic) +#endif diff --git a/sysdeps/sparc/sparc64/rtld-memset.c b/sysdeps/sparc/sparc64/rtld-memset.c index 55f3835790..a19202a620 100644 --- a/sysdeps/sparc/sparc64/rtld-memset.c +++ b/sysdeps/sparc/sparc64/rtld-memset.c @@ -1 +1,4 @@ #include +#if IS_IN(rtld) +strong_alias (memset, __memset_ultra1) +#endif