From patchwork Wed May 17 18:54:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 1782922 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.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=HagnKtrM; 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 ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QM2N9551Pz20KF for ; Thu, 18 May 2023 04:54:49 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B52033836E88 for ; Wed, 17 May 2023 18:54:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B52033836E88 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1684349687; bh=jA+8Hoam1g9QjOuGLj8ZNIc1FOg+23Ll4j5AgXsGWcM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=HagnKtrMCz1SK7zEd+HHFkEbjw/xq9mgzwpgYyNCUMPCD1MgIO9m99sphzvVzuwQ7 KZRyaRp0RcH98tzGUWvvOJZu2dvxbEL8+DUJjOnl0nO9OJwtVztETiKoiZEYgRqXDs skn7R/5xHn2LHqfrGnl1ttK+6b1I7PW3Vz3ODxd0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lj1-x22a.google.com (mail-lj1-x22a.google.com [IPv6:2a00:1450:4864:20::22a]) by sourceware.org (Postfix) with ESMTPS id 2DD91384645F for ; Wed, 17 May 2023 18:54:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2DD91384645F Received: by mail-lj1-x22a.google.com with SMTP id 38308e7fff4ca-2ac8c0fbb16so11293851fa.2 for ; Wed, 17 May 2023 11:54:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684349665; x=1686941665; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jA+8Hoam1g9QjOuGLj8ZNIc1FOg+23Ll4j5AgXsGWcM=; b=ZesmeDMVwHrWfufRmM7tcPxhFO0+CI+BEM0Zyk7qeELoyWFvwDliyy5h23oxoZtGdx skF4Mli1+Eko8VlG8d7ZoOteo25BARikRuzb/LkMHdrBJkv2d3nRkOtj1luZMxzlW74u fYVuVNFp97VXTMdqEvYQftuJ83J7BfaLIdvUEGJfPMs4Tg3s3vPBTBzdZdMc7ITX/beK G9ruFJGWVFn31r8OZb72BmauQQACM22l2haWDlWuKTjeIkEU28axkDq5iLGW4NRcZ8Br fAIPc/zPRo/zgN72F1qj8h+jqvk22qhl2trcCPmdLlLLc7jOh030BBDijdD/3DXzXhxh H/sg== X-Gm-Message-State: AC+VfDzH1SxXzG+6UL5WKpAXnefXxUm4XeUXxInLkwNwcqcDIFsOPadg 0Ap4SnSa95lEXCoW6NiT1OgcEdhwmGY= X-Google-Smtp-Source: ACHHUZ4M0FDh8iuuT1sKLXGHDgQ1cJN52wXGCRl7vV+/70pTG+VGj6Fs+6cSyqTaFI/37RnM1iHV7w== X-Received: by 2002:a05:6512:515:b0:4ef:eb86:b9c7 with SMTP id o21-20020a056512051500b004efeb86b9c7mr599344lfb.49.1684349665114; Wed, 17 May 2023 11:54:25 -0700 (PDT) Received: from surface-pro-6.. ([194.190.106.50]) by smtp.gmail.com with ESMTPSA id s23-20020a2e9c17000000b002ad90280503sm4052326lji.138.2023.05.17.11.54.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 May 2023 11:54:24 -0700 (PDT) To: libc-alpha@sourceware.org, bug-hurd@gnu.org Subject: [RFC PATCH 1/2] elf: Port ldconfig away from stack-allocated paths Date: Wed, 17 May 2023 21:54:21 +0300 Message-Id: <20230517185422.71084-2-bugaevc@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230517185422.71084-1-bugaevc@gmail.com> References: <20230517185422.71084-1-bugaevc@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham 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.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sergey Bugaev via Libc-alpha From: Sergey Bugaev Reply-To: Sergey Bugaev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" ldconfig was allocating PATH_MAX bytes on the stack for the library file name. The issues with PATH_MAX usage are well documented [0][1]; even if a program does not rely on paths being limited to PATH_MAX bytes, allocating 4096 bytes on the stack for paths that are typically rather short (strlen ("/lib64/libc.so.6") is 16) is wasteful and dangerous. [0]: https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html [1]: https://eklitzke.org/path-max-is-tricky Instead, make use of asprintf to dynamically allocate memory of just the right size on the heap. Checked on x86_64-linux-gnu and i686-gnu. Signed-off-by: Sergey Bugaev Reviewed-by: Adhemerval Zanella Reviewed-by: Adhemerval Zanella Signed-off-by: Sergey Bugaev Reviewed-by: Florian Weimer --- elf/ldconfig.c | 59 +++++++++++++++++--------------------------------- 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/elf/ldconfig.c b/elf/ldconfig.c index 2fc45ad8..7f2e4226 100644 --- a/elf/ldconfig.c +++ b/elf/ldconfig.c @@ -677,28 +677,18 @@ search_dir (const struct dir_entry *entry) char *dir_name; char *real_file_name; - size_t real_file_name_len; - size_t file_name_len = PATH_MAX; - char *file_name = alloca (file_name_len); + char *file_name; if (opt_chroot != NULL) - { - dir_name = chroot_canon (opt_chroot, entry->path); - real_file_name_len = PATH_MAX; - real_file_name = alloca (real_file_name_len); - } + dir_name = chroot_canon (opt_chroot, entry->path); else - { - dir_name = entry->path; - real_file_name_len = 0; - real_file_name = file_name; - } + dir_name = entry->path; DIR *dir; if (dir_name == NULL || (dir = opendir (dir_name)) == NULL) { if (opt_verbose) error (0, errno, _("Can't open directory %s"), entry->path); - if (opt_chroot != NULL && dir_name != NULL) + if (opt_chroot != NULL) free (dir_name); return; } @@ -733,25 +723,11 @@ search_dir (const struct dir_entry *entry) + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0) continue; } - len += strlen (entry->path) + 2; - if (len > file_name_len) - { - file_name_len = len; - file_name = alloca (file_name_len); - if (!opt_chroot) - real_file_name = file_name; - } - sprintf (file_name, "%s/%s", entry->path, direntry->d_name); + asprintf (&file_name, "%s/%s", entry->path, direntry->d_name); if (opt_chroot != NULL) - { - len = strlen (dir_name) + strlen (direntry->d_name) + 2; - if (len > real_file_name_len) - { - real_file_name_len = len; - real_file_name = alloca (real_file_name_len); - } - sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name); - } + asprintf (&real_file_name, "%s/%s", dir_name, direntry->d_name); + else + real_file_name = file_name; struct stat lstat_buf; /* We optimize and try to do the lstat call only if needed. */ @@ -761,7 +737,7 @@ search_dir (const struct dir_entry *entry) if (__glibc_unlikely (lstat (real_file_name, &lstat_buf))) { error (0, errno, _("Cannot lstat %s"), file_name); - continue; + goto next; } struct stat stat_buf; @@ -778,7 +754,7 @@ search_dir (const struct dir_entry *entry) { if (strstr (file_name, ".so") == NULL) error (0, 0, _("Input file %s not found.\n"), file_name); - continue; + goto next; } } if (__glibc_unlikely (stat (target_name, &stat_buf))) @@ -793,7 +769,7 @@ search_dir (const struct dir_entry *entry) if (opt_chroot != NULL) free (target_name); - continue; + goto next; } if (opt_chroot != NULL) @@ -806,7 +782,7 @@ search_dir (const struct dir_entry *entry) lstat_buf.st_ctime = stat_buf.st_ctime; } else if (!S_ISREG (lstat_buf.st_mode)) - continue; + goto next; char *real_name; if (opt_chroot != NULL && is_link) @@ -816,7 +792,7 @@ search_dir (const struct dir_entry *entry) { if (strstr (file_name, ".so") == NULL) error (0, 0, _("Input file %s not found.\n"), file_name); - continue; + goto next; } } else @@ -828,7 +804,7 @@ search_dir (const struct dir_entry *entry) && __builtin_expect (lstat (real_file_name, &lstat_buf), 0)) { error (0, errno, _("Cannot lstat %s"), file_name); - continue; + goto next; } /* First search whether the auxiliary cache contains this @@ -842,7 +818,7 @@ search_dir (const struct dir_entry *entry) { if (real_name != real_file_name) free (real_name); - continue; + goto next; } else if (opt_build_cache) add_to_aux_cache (&lstat_buf, flag, isa_level, soname); @@ -948,6 +924,11 @@ search_dir (const struct dir_entry *entry) dlib_ptr->next = dlibs; dlibs = dlib_ptr; } + + next: + free (file_name); + if (opt_chroot != NULL) + free (real_file_name); } closedir (dir);