]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Update Solaris execve with checks for NULL argv
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 10 Apr 2022 21:02:13 +0000 (23:02 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 10 Apr 2022 21:02:13 +0000 (23:02 +0200)
Also requires 2 expected to be updated

coregrind/m_syswrap/syswrap-solaris.c
memcheck/tests/solaris/execx.stderr.exp
memcheck/tests/solaris/scalar.stderr.exp

index ea460734274bcc6f8f4a92975dcc9d9bd940bc69..992fbeb9c43843d78b129b1395e1d56adaabc33c 100644 (file)
@@ -3618,6 +3618,10 @@ PRE(sys_fdsync)
 PRE(sys_execve)
 {
    Int i, j;
+   Addr arg_2_check;
+   const char* str2 = "execve(argv)";
+   const char* str3 = "execve(argv[0])";
+   const char* str4 = "execve(argv[i])";
    /* This is a Solaris specific version of the generic pre-execve wrapper. */
 
 #if defined(SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS)
@@ -3645,12 +3649,8 @@ PRE(sys_execve)
 
    if (ARG1_is_fd == False)
       PRE_MEM_RASCIIZ("execve(filename)", ARG1);
-   if (ARG2)
-      ML_(pre_argv_envp)(ARG2, tid, "execve(argv)", "execve(argv[i])");
-   if (ARG3)
-      ML_(pre_argv_envp)(ARG3, tid, "execve(envp)", "execve(envp[i])");
-
-   /* Erk.  If the exec fails, then the following will have made a mess of
+   
+    /* Erk.  If the exec fails, then the following will have made a mess of
       things which makes it hard for us to continue.  The right thing to do is
       piece everything together again in POST(execve), but that's close to
       impossible.  Instead, we make an effort to check that the execve will
@@ -3678,6 +3678,34 @@ PRE(sys_execve)
          VG_(unimplemented)("Syswrap of execve where fd points to a hardlink.");
    }
 
+   arg_2_check = (Addr)ARG2;
+
+   /* argv[] should not be NULL and valid.  */
+   PRE_MEM_READ(str2, arg_2_check, sizeof(Addr));
+
+   /* argv[0] should not be NULL and valid.  */
+   if (ML_(safe_to_deref)((HChar **) (Addr)arg_2_check, sizeof(HChar *))) {
+      Addr argv0 = *(Addr*)arg_2_check;
+      PRE_MEM_RASCIIZ( str3, argv0 );
+      /* The rest of argv can be NULL or a valid string pointer.  */
+      if (VG_(am_is_valid_for_client)(arg_2_check, sizeof(HChar), VKI_PROT_READ)) {
+         arg_2_check += sizeof(HChar*);
+         ML_(pre_argv_envp)( arg_2_check, tid, str2, str4 );
+       }
+   } else {
+      SET_STATUS_Failure(VKI_EFAULT);
+      return;
+    }
+
+   if (ARG3 != 0) {
+      /* At least the terminating NULL must be addressable. */
+      if (!ML_(safe_to_deref)((HChar **) (Addr)ARG3, sizeof(HChar *))) {
+         SET_STATUS_Failure(VKI_EFAULT);
+         return;
+      }
+      ML_(pre_argv_envp)( ARG3, tid, "execve(envp)", "execve(envp[i])" );
+   }
+
    /* Check that the name at least begins in client-accessible storage. */
    if (ARG1_is_fd == False) {
       if ((fname == NULL) || !ML_(safe_to_deref)(fname, 1)) {
index 9e86cbdf843d287bb5f348194d1bea5c28bc3ddc..30c885b72cbf88ac480f22187f0710179fd40484 100644 (file)
@@ -2,3 +2,7 @@ Syscall param execve(filename) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
+Syscall param execve(argv) points to unaddressable byte(s)
+   ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
index df1f974758f945a5f54e033d8e7a398af4eb5407..1a04979d199b5df1c239ccce8da676bfe5c74640 100644 (file)
@@ -1011,6 +1011,10 @@ Syscall param execve(filename) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
+Syscall param execve(argv) points to unaddressable byte(s)
+   ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
 ---------------------------------------------------------
  60:               SYS_umask 1s 0m
 ---------------------------------------------------------