]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 396415 - Valgrind is not looking up $ORIGIN rpath of shebang programs
authorPaul Floyd <pjfloyd@wanadoo.fr>
Thu, 6 Feb 2025 19:23:42 +0000 (20:23 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Thu, 6 Feb 2025 19:23:42 +0000 (20:23 +0100)
NEWS
coregrind/m_initimg/initimg-darwin.c
coregrind/m_initimg/initimg-freebsd.c
coregrind/m_initimg/initimg-linux.c
coregrind/m_initimg/initimg-solaris.c
coregrind/m_ume/elf.c
coregrind/m_ume/macho.c
none/tests/freebsd/Makefile.am
none/tests/freebsd/auxv_script [new file with mode: 0755]
none/tests/freebsd/auxv_script.stderr.exp [new file with mode: 0644]
none/tests/freebsd/auxv_script.vgtest [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index ca5bfb23f49b5b15dba84e7803bb0e085eef5a53..1c627c7744f08cf2b75c5ce4e072f2ef31fbabc4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,7 @@ bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather
 than mailing the developers (or mailing lists) directly -- bugs that
 are not entered into bugzilla tend to get forgotten about or ignored.
 
+396415  Valgrind is not looking up $ORIGIN rpath of shebang programs
 487296  --track-fds=yes and --track-fds=all report erroneous information
         when fds 0, 1, or 2 are used as non-std
 489913  WARNING: unhandled amd64-linux syscall: 444 (landlock_create_ruleset)
index 7bac7dc0d18ce2145bc3051688a6e7589165059e..57fbd0bf75cd88cd1deb4f0e79a50cb12f7790fa 100644 (file)
@@ -61,7 +61,6 @@ static void load_client ( /*OUT*/ExeInfo* info,
 {
    const HChar* exe_name;
    Int    ret;
-   SysRes res;
 
    vg_assert( VG_(args_the_exename) != NULL);
    exe_name = VG_(find_executable)( VG_(args_the_exename) );
@@ -76,12 +75,6 @@ static void load_client ( /*OUT*/ExeInfo* info,
 
    // The client was successfully loaded!  Continue.
 
-   /* Get hold of a file descriptor which refers to the client
-      executable.  This is needed for attaching to GDB. */
-   res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
-   if (!sr_isError(res))
-      VG_(cl_exec_fd) = sr_Res(res);
-
    /* Copy necessary bits of 'info' that were filled in */
    *client_ip  = info->init_ip;
 }
index 6749e849fc544125a5a2203616a4a0bc1626cb4c..cb98eb91445688ede8d75ff81864490fa077b8a0 100644 (file)
@@ -64,7 +64,6 @@ static void load_client ( /*OUT*/ExeInfo* info,
 {
    const HChar* exe_name;
    Int    ret;
-   SysRes res;
 
    vg_assert( VG_(args_the_exename) != NULL);
    exe_name = VG_(find_executable)( VG_(args_the_exename) );
@@ -83,13 +82,6 @@ static void load_client ( /*OUT*/ExeInfo* info,
 
    // The client was successfully loaded!  Continue.
 
-   /* Get hold of a file descriptor which refers to the client
-      executable.  This is needed for attaching to GDB. */
-   res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
-   if (!sr_isError(res)) {
-      VG_(cl_exec_fd) = sr_Res(res);
-   }
-
    /* Copy necessary bits of 'info' that were filled in */
    *client_ip  = info->init_ip;
    *client_toc = info->init_toc;
@@ -342,6 +334,53 @@ static const struct auxv *find_auxv(const UWord* sp)
    return (const struct auxv *)sp;
 }
 
+static Bool try_get_interp(const HChar* args_exe, HChar* interp_out)
+{
+   HChar  hdr[4096];
+   Int    len = sizeof hdr;
+   SysRes res;
+   Int fd;
+   HChar* end;
+   HChar* cp;
+   HChar* interp;
+
+   res = VG_(open)(args_exe, VKI_O_RDONLY, 0);
+   if (sr_isError(res)) {
+      return False;
+   } else {
+      fd = sr_Res(res);
+   }
+
+   res = VG_(pread)(fd, hdr, len, 0);
+
+   if (sr_isError(res)) {
+      VG_(close)(fd);
+      return False;
+   } else {
+      len = sr_Res(res);
+   }
+
+   if (0 != VG_(memcmp)(hdr, "#!", 2)) {
+       VG_(close)(fd);
+      return False;
+   }
+
+   end    = hdr + len;
+   interp = hdr + 2;
+   while (interp < end && (*interp == ' ' || *interp == '\t'))
+      interp++;
+
+   for (cp = interp; cp < end && !VG_(isspace)(*cp); cp++)
+      ;
+
+   *cp = '\0';
+
+   VG_(sprintf)(interp_out, "%s", interp);
+
+   VG_(close)(fd);
+   return True;
+}
+
 /* ----------------------------------------------------------------
 
    This sets up the client's initial stack, containing the args,
@@ -425,6 +464,10 @@ static Addr setup_client_stack(const void*  init_sp,
    vg_assert( VG_(args_for_client) );
 
    const HChar *exe_name = VG_(find_executable)(VG_(args_the_exename));
+   HChar interp_name[VKI_PATH_MAX];
+   if (try_get_interp(exe_name, interp_name)) {
+      exe_name = interp_name;
+   }
    HChar resolved_name[VKI_PATH_MAX];
    VG_(realpath)(exe_name, resolved_name);
 
index 5359189bf69181f8f22317c1a7ac9d5a8b6b5988..feec1e5f118def67892bf93dcf08319c04b9b894 100644 (file)
@@ -70,7 +70,6 @@ static void load_client ( /*MOD*/ExeInfo* info,
 {
    const HChar* exe_name;
    Int    ret;
-   SysRes res;
 
    vg_assert( VG_(args_the_exename) != NULL);
    exe_name = VG_(find_executable)( VG_(args_the_exename) );
@@ -88,12 +87,6 @@ static void load_client ( /*MOD*/ExeInfo* info,
 
    // The client was successfully loaded!  Continue.
 
-   /* Get hold of a file descriptor which refers to the client
-      executable.  This is needed for attaching to GDB. */
-   res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
-   if (!sr_isError(res))
-      VG_(cl_exec_fd) = sr_Res(res);
-
    /* Copy necessary bits of 'info' that were filled in */
    *client_ip  = info->init_ip;
    *client_toc = info->init_toc;
index 1e9e3fd061ea51939282bcadcda0780c726faeae..4fa94b8c4c659ad1318a653bd3cfaff8b836bf97 100644 (file)
@@ -65,7 +65,6 @@ static void load_client(/*OUT*/ExeInfo *info,
 {
    const HChar *exe_name;
    Int ret;
-   SysRes res;
 
    vg_assert(VG_(args_the_exename));
    exe_name = VG_(find_executable)(VG_(args_the_exename));
@@ -96,12 +95,6 @@ static void load_client(/*OUT*/ExeInfo *info,
    }
    VG_(strcpy)(out_exe_name, exe_name);
 
-   /* Get hold of a file descriptor which refers to the client executable.
-      This is needed for attaching to GDB. */
-   res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
-   if (!sr_isError(res))
-      VG_(cl_exec_fd) = sr_Res(res);
-
    /* Set initial brk values. */
    if (info->ldsoexec) {
       VG_(brk_base) = VG_(brk_limit) = -1;
index a850a50cfa56b22830cd54f635afef69bc25342a..bad7e5ee6b4cb9ceea9e02a5feb5d99b0b192935 100644 (file)
@@ -41,6 +41,7 @@
 #include "pub_core_mallocfree.h"    // VG_(malloc), VG_(free)
 #include "pub_core_vkiscnums.h"
 #include "pub_core_syscall.h"       // VG_(strerror)
+#include "pub_core_clientstate.h"
 #include "pub_core_ume.h"           // self
 
 #include "priv_ume.h"
@@ -876,6 +877,12 @@ Int VG_(load_ELF)(Int fd, const HChar* name, /*MOD*/ExeInfo* info)
    VG_(free)(e->p);
    VG_(free)(e);
 
+   /* Get hold of a file descriptor which refers to the client
+      executable.  This is needed for attaching to GDB. */
+   SysRes res = VG_(dup)(fd);
+   if (!sr_isError(res))
+      VG_(cl_exec_fd) = sr_Res(res);
+
    return 0;
 }
 
index 046d17493389ac1d665bff363239daa78ccf0990..6d65574e44aecd56703f8e3bdf408534c2c8ee24 100644 (file)
@@ -41,6 +41,7 @@
 #include "pub_core_machine.h"       // VG_ELF_CLASS (XXX: which should be moved)
 #include "pub_core_mallocfree.h"    // VG_(malloc), VG_(free)
 #include "pub_core_syscall.h"       // VG_(strerror)
+#include "pub_core_clientstate.h"
 #include "pub_core_ume.h"           // self
 
 #include "priv_ume.h"
@@ -857,6 +858,10 @@ Int VG_(load_macho)(Int fd, const HChar *name, ExeInfo *info)
 
    info->executable_path = VG_(strdup)("ume.macho.executable_path", name);
 
+   SysRes res = VG_(dup)(fd);
+   if (!sr_isError(res))
+      VG_(cl_exec_fd) = sr_Res(res);
+
    return 0;
 }
 
index d1f7759ec9ca3d850eaec78d382e6435b20a024f..667445aa15639f9d73e46bc8a9629e56044ee1b1 100644 (file)
@@ -11,6 +11,8 @@ EXTRA_DIST = \
        auxv.stderr.exp-freebsd131 \
        auxv.stderr.exp-freebsd14 \
        auxv.stderr.exp-arm64 \
+       auxv_script.vgtest \
+       auxv_script.stderr.exp \
        bug452274.vgtest \
        bug452274.stderr.exp \
        bug498317.vgtest bug498317.stderr.exp \
diff --git a/none/tests/freebsd/auxv_script b/none/tests/freebsd/auxv_script
new file mode 100755 (executable)
index 0000000..7794012
--- /dev/null
@@ -0,0 +1 @@
+#!./auxv
diff --git a/none/tests/freebsd/auxv_script.stderr.exp b/none/tests/freebsd/auxv_script.stderr.exp
new file mode 100644 (file)
index 0000000..dcca09f
--- /dev/null
@@ -0,0 +1,29 @@
+val: AT_PHDR int: 03 ptr: 0x........
+val: AT_PHENT int: 04 ptr: 0x........
+val: AT_PHNUM int: 05 ptr: 0x........
+val: AT_PAGESZ int: 06 ptr: 0x........
+val: AT_FLAGS int: 08 ptr: 0x........
+val: AT_ENTRY int: 09 ptr: 0x........
+val: AT_BASE int: 07 ptr: 0x........
+val: AT_EHDRFLAGS int: 24 ptr: 0x........
+val: AT_EXECPATH int: 15 ptr: 0x........
+EXECPATH: BASEDIR/valgrind/none/tests/freebsd/auxv
+val: AT_OSRELDATE int: 18 ptr: 0x........
+val: AT_CANARY int: 16 ptr: 0x........
+val: AT_CANARYLEN int: 17 ptr: 0x........
+val: AT_NCPUS int: 19 ptr: 0x........
+val: AT_PAGESIZES int: 20 ptr: 0x........
+val: AT_PAGESIZESLEN int: 21 ptr: 0x........
+val: AT_IGNORE int: 01 ptr: 0x........
+val: AT_STACKPROT int: 23 ptr: 0x........
+val: AT_IGNORE int: 01 ptr: 0x........
+val: AT_ARGC int: 28 ptr: 0x........
+val: AT_ARGV int: 29 ptr: 0x........
+ARGV: ./auxv
+val: AT_ENVC int: 30 ptr: 0x........
+val: AT_ENVV int: 31 ptr: 0x........
+val: AT_PS_STRINGS int: 32 ptr: 0x........
+PS_STRINGS ARGV: ./auxv
+val: AT_IGNORE int: 01 ptr: 0x........
+val: AT_USRSTACKBASE int: 35 ptr: 0x........
+val: AT_USRSTACKLIM int: 36 ptr: 0x........
diff --git a/none/tests/freebsd/auxv_script.vgtest b/none/tests/freebsd/auxv_script.vgtest
new file mode 100644 (file)
index 0000000..ccd450a
--- /dev/null
@@ -0,0 +1,4 @@
+prog: auxv_script
+vgopts: -q
+stderr_filter: filter_auxv
+