From patchwork Fri Oct 21 15:20:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Asaf Fisher X-Patchwork-Id: 59295 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9C2053853810 for ; Fri, 21 Oct 2022 15:22:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9C2053853810 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1666365734; bh=pxF0uq36TfOoA3/JPbu4B3+6k/U7iqxaTIWeDUKlAwg=; 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=hi01xeGHfI7cfQ5BjIWJATl3AY3bY2FdPDDdpJxaROG5nfuhoBTbabnbGxM4WIde8 g/RkEjcoYC8GG61yVzrRtgKmqJsaLvNnI8WYj+qOj9BuADJEx2fsYx4obTz8ay8FtN eucKFrQr3HMsShdKsdsFewTZXgz+VzoAdbgk7ivw= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by sourceware.org (Postfix) with ESMTPS id ED7873856DC0 for ; Fri, 21 Oct 2022 15:20:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org ED7873856DC0 Received: by mail-ed1-x534.google.com with SMTP id t16so7147593edd.2 for ; Fri, 21 Oct 2022 08:20:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=pxF0uq36TfOoA3/JPbu4B3+6k/U7iqxaTIWeDUKlAwg=; b=2zPV9StcUM4Ku5HbDjuX6a42SxdnDAWe+7TxFNEsXN44XTBn7t0M/oL6/uzivPYBCt rQ0Y7U+cpHb9HHWtI93aVfYDQ1hTOPUNG69nNoC9y4yw9GH4RnrCydOHEnq5/Wg7GXxi rWHVsaFARA0OyaJClxwJ3fN1Bry/85VPg7pI60237LJ5Vty4BwUty5ag7R7+VP5wz5hX Ar27evAQwd2+/qjJjiht9CTaUOrwl/ugdZ0M4tDkQo/tr3pcYq7uQ6x//iU5jPs7KJZp jGI0yeLZ4m8HviBpoeWb+Clj6tAIj5nRrpnq9bORpuZVlnCy/yGDsTJVa1y/c3XDxhsA JLjA== X-Gm-Message-State: ACrzQf3uGE3wrGsEuAlglXqg5Z3M1BtCWSwgkQlNKg9k30NQ4UcbL+j0 G71boLbheRpZ293Lh5yL0mbbiAHT57JQPY3/ X-Google-Smtp-Source: AMsMyM7ViNHCnyacjPtRMn1u5WkBBggCnil/SUJJELwULPYHByOdJkmt5Akh+S9rmCI6D0SAq3E9Cw== X-Received: by 2002:a05:6402:11ce:b0:45c:a364:2c3d with SMTP id j14-20020a05640211ce00b0045ca3642c3dmr18160803edw.204.1666365657710; Fri, 21 Oct 2022 08:20:57 -0700 (PDT) Received: from codespaces-99e6ae.cwehd3ikdxye1e5jw03kh0ngkf.ax.internal.cloudapp.net ([104.40.192.11]) by smtp.gmail.com with ESMTPSA id v25-20020a17090651d900b0078da24ea9c7sm11878894ejk.17.2022.10.21.08.20.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Oct 2022 08:20:57 -0700 (PDT) To: gdb-patches@sourceware.org Subject: [PATCH v2 2/2] Make GDB resolve dlopen of memory mapped shared libraries Date: Fri, 21 Oct 2022 15:20:46 +0000 Message-Id: <20221021152046.22005-2-asaffisher.dev@gmail.com> X-Mailer: git-send-email 2.38.0 In-Reply-To: <20221021152046.22005-1-asaffisher.dev@gmail.com> References: <20221021152046.22005-1-asaffisher.dev@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 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 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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Asaf Fisher via Gdb-patches From: Asaf Fisher Reply-To: Asaf Fisher Cc: Asaf Fisher Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Introduced `check_proc_self_file` that checks if a path used by inferior in dlopen is in the form of `/proc/self/...` and if so resolves it to `/proc/[pid]/...` Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29586 --- gdb/solib-svr4.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 6acaf87960b..0cdb2dff6c3 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -34,6 +34,7 @@ #include "regcache.h" #include "gdbthread.h" #include "observable.h" +#include "gdbsupport/pathstuff.h" #include "solist.h" #include "solib.h" @@ -48,6 +49,9 @@ #include +#define SLASH_SELF "/self" +#define PROC_SELF "/proc" SLASH_SELF + static struct link_map_offsets *svr4_fetch_link_map_offsets (void); static int svr4_have_link_map_offsets (void); static void svr4_relocate_main_executable (void); @@ -1259,6 +1263,54 @@ svr4_default_sos (svr4_info *info) return newobj; } +/* Check and fix a cenerio where the so path that we extract has a path to + /proc/self e.g. /proc/self/fd/[fd_num] If inferior dlopen a path that has + /proc/self, GDB must not open it directly becuase the files in /proc/self are + unique for each process. Instead we resolve /proc/self to + /proc/[inferior_pid]. This change will give GDB the correct path */ + +static size_t check_proc_self_file(char *so_name, char *normalized_so_name, + size_t out_normalized_so_name_len) { + /* We dont want a path with /../ yak. */ + gdb::unique_xmalloc_ptr normalized_path_obj = gdb_realpath(so_name); + gdb::string_view normalized_path = gdb::string_view( + normalized_path_obj.get(), + std::min(strlen(normalized_path_obj.get()), out_normalized_so_name_len)); + + /* Is the path really a /proc/self? */ + if (0 != normalized_path.rfind(PROC_SELF, 0)) return 0; + + /* Lets get the part of the path after /proc/self e.g. /proc/self/fd -> /fd */ + size_t slash_self_index = normalized_path.rfind(SLASH_SELF); + if (std::string::npos == slash_self_index) return 0; + size_t after_self_index = slash_self_index + strlen(SLASH_SELF); + gdb::string_view after_self_path = normalized_path.substr(after_self_index); + + /* Get inferior path */ + int inferior_pid = inferior_ptid.pid(); + std::string inferior_procfs_path = string_printf("/proc/%d", inferior_pid); + + /* Check if there's enoght space in the out buffer for the normalized path. */ + size_t normalized_so_name_length = + inferior_procfs_path.length() + after_self_path.length(); + if (out_normalized_so_name_len < normalized_so_name_length) return 0; + + /* Build the full path */ + inferior_procfs_path.append(std::string(after_self_path)); + + warning(_("Detected loaded library (%s) from /proc/self.\nAttempting to " + "replace `self` with inferior's PID. -> %s"), + normalized_path.begin(), inferior_procfs_path.c_str()); + + auto out_length = + std::min(inferior_procfs_path.length(), out_normalized_so_name_len); + + /* Copy the new path to the out buffer */ + strncpy(normalized_so_name, inferior_procfs_path.c_str(), out_length); + + return out_length; +} + /* Read the whole inferior libraries chain starting at address LM. Expect the first entry in the chain's previous entry to be PREV_LM. Add the entries to the tail referenced by LINK_PTR_PTR. Ignore the @@ -1318,8 +1370,10 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, warning (_("Can't read pathname for load map.")); continue; } - - strncpy (newobj->so_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); + /* Check if path is in /proc/self */ + if (0 == check_proc_self_file(buffer.get(), newobj->so_name, + SO_NAME_MAX_PATH_SIZE - 1)) + strncpy(newobj->so_name, buffer.get(), SO_NAME_MAX_PATH_SIZE - 1); newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; strcpy (newobj->so_original_name, newobj->so_name);