]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
The linux launcher showed some odd behaviour. When given a shell script
authorFlorian Krohm <florian@eich-krohm.de>
Mon, 6 Apr 2015 14:29:45 +0000 (14:29 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Mon, 6 Apr 2015 14:29:45 +0000 (14:29 +0000)
named 'now' with this contents:

#!
/bin/date

the platform selection logic does this:

--11196:1:launcher no tool requested, defaulting to 'memcheck'
--11196:2:launcher   selecting platform for './now'
--11196:2:launcher   selecting platform for './now'
--11196:2:launcher   opened './now'
--11196:2:launcher   read 13 bytes from './now'
--11196:2:launcher   selecting platform for ''
--11196:2:launcher   selecting platform for '/home/florian/bin/'
--11196:2:launcher   opened '/home/florian/bin/'
--11196:2:launcher   selected platform 'unknown'
--11196:1:launcher no platform detected, defaulting platform to 'amd64-linux'

That is not quite right. Instead the platform should be determined by
examining the default shell.
Additionally, define VKI_BINPRM_BUF_SIZE because on linux only that many
characters are considered on a #! line. C.f. <linux>/fs/binfmt_script.c
m_ume/* needs to be adapted as well but that is a different patch.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15068

coregrind/launcher-linux.c
include/vki/vki-linux.h

index c7f486917faf0fe289a9dd8de57e74c9d627679f..53c8d83e226079a2a1d53b8731033b7a7c2e52bc 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
 
 /*--------------------------------------------------------------------*/
 /*--- Launching valgrind                              m_launcher.c ---*/
@@ -156,24 +157,39 @@ static const char *select_platform(const char *clientname)
 
    if (header[0] == '#' && header[1] == '!') {
       int i = 2;
-      char *interp = (char *)header + 2;
 
+      STATIC_ASSERT(VKI_BINPRM_BUF_SIZE < sizeof header);
+      if (n_bytes > VKI_BINPRM_BUF_SIZE)
+         n_bytes = VKI_BINPRM_BUF_SIZE - 1;
+      header[n_bytes] = '\0';
+      char *eol = strchr(header, '\n');
+      if (eol != NULL)
+         *eol = '\0';
       // Skip whitespace.
-      while (1) {
-         if (i == n_bytes) return NULL;
-         if (' ' != header[i] && '\t' != header[i]) break;
+      while  (header[i] == ' '|| header[i] == '\t')
          i++;
-      }
 
       // Get the interpreter name.
-      interp = &header[i];
-      while (1) {
-         if (i == n_bytes) break;
-         if (isspace(header[i])) break;
-         i++;
+      const char *interp = header + i;
+
+      if (header[i] == '\0') {
+         // No interpreter was found; fall back to default shell
+#  if defined(VGPV_arm_linux_android) \
+      || defined(VGPV_x86_linux_android) \
+      || defined(VGPV_mips32_linux_android) \
+      || defined(VGPV_arm64_linux_android)
+         interp = "/system/bin/sh";
+#  else
+         interp = "/bin/sh";
+#  endif
+      } else {
+         while (header[i]) {
+            if (header[i] == ' ' || header[i] == '\t') break;
+            i++;
+         }
+         header[i] = '\0';
       }
-      if (i == n_bytes) return NULL;
-      header[i] = '\0';
 
       platform = select_platform(interp);
 
index a66b8bc6cb43bf97775dad0ce12f235fddced243..42b24fe329be5927465124c444323b5d2c9313e8 100644 (file)
@@ -4610,6 +4610,11 @@ enum vki_kcmp_type {
 
 #define VKI_SECCOMP_MODE_FILTER 2
 
+//----------------------------------------------------------------------
+// From linux-3.19.3/include/uapi/linux/binfmts.h
+//----------------------------------------------------------------------
+#define VKI_BINPRM_BUF_SIZE 128
+
 #endif // __VKI_LINUX_H
 
 /*--------------------------------------------------------------------*/