]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Improve handling of clone() on x86/Linux. Based on a patch from Jeroen
authorNicholas Nethercote <njn@valgrind.org>
Mon, 20 Jul 2009 05:48:44 +0000 (05:48 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Mon, 20 Jul 2009 05:48:44 +0000 (05:48 +0000)
Witmond.  This fixes bug 117564.

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

coregrind/m_syswrap/syswrap-x86-linux.c
memcheck/tests/x86-linux/scalar.c
memcheck/tests/x86-linux/scalar.stderr.exp

index 601ff941afd1d8a1ccffac44c6cd0f438568b20c..bec9c1fc35daf508e7403bfa0837429ff794abb2 100644 (file)
@@ -835,38 +835,47 @@ PRE(old_select)
 PRE(sys_clone)
 {
    UInt cloneflags;
+   Bool badarg = False;
 
    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
-   PRE_REG_READ5(int, "clone",
+   PRE_REG_READ2(int, "clone",
                  unsigned long, flags,
-                 void *, child_stack,
-                 int *, parent_tidptr,
-                 vki_modify_ldt_t *, tlsinfo,
-                 int *, child_tidptr);
+                 void *, child_stack);
 
    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
+      if (VG_(tdict).track_pre_reg_read) {
+         PRA3("clone", int *, parent_tidptr);
+      }
       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), 
                                              VKI_PROT_WRITE)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         return;
+         badarg = True;
+      }
+   }
+   if (ARG1 & VKI_CLONE_SETTLS) {
+      if (VG_(tdict).track_pre_reg_read) {
+         PRA4("clone", vki_modify_ldt_t *, tlsinfo);
+      }
+      PRE_MEM_READ("clone(tlsinfo)", ARG4, sizeof(vki_modify_ldt_t));
+      if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t), 
+                                             VKI_PROT_READ)) {
+         badarg = True;
       }
    }
    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
+      if (VG_(tdict).track_pre_reg_read) {
+         PRA5("clone", int *, child_tidptr);
+      }
       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
       if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int), 
                                              VKI_PROT_WRITE)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         return;
+         badarg = True;
       }
    }
-   if (ARG1 & VKI_CLONE_SETTLS) {
-      PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
-      if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t), 
-                                             VKI_PROT_READ)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         return;
-      }
+
+   if (badarg) {
+      SET_STATUS_Failure( VKI_EFAULT );
+      return;
    }
 
    cloneflags = ARG1;
index 97357d1f948f4390d52d87b488df2a31a8dfe53a..1ba7c38b88698a02c6c8870242a6a165f11186b5 100644 (file)
@@ -550,9 +550,8 @@ int main(void)
 #ifndef CLONE_PARENT_SETTID
 #define CLONE_PARENT_SETTID    0x00100000
 #endif
-   // XXX: should really be "4s 2m"?  Not sure... (see PRE(sys_clone))
-   GO(__NR_clone, "4s 0m");
-   SY(__NR_clone, x0|CLONE_PARENT_SETTID|SIGCHLD, x0, x0, x0); FAIL;
+   GO(__NR_clone, "5s 3m");
+   SY(__NR_clone, x0|CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID|SIGCHLD, x0, x0, x0, x0); FAIL;
    if (0 == res) {
       SY(__NR_exit, 0); FAIL;
    }
index abfb75f85b335d15a1fb11436d4633a47296b704..40ae1b77e7fec41476919cd70677808cc08c4be4 100644 (file)
@@ -1142,7 +1142,7 @@ Syscall param fsync(fd) contains uninitialised byte(s)
 119:      __NR_sigreturn n/a
 -----------------------------------------------------
 -----------------------------------------------------
-120:          __NR_clone 4s 0m
+120:          __NR_clone 5s 3m
 -----------------------------------------------------
 
 Syscall param clone(flags) contains uninitialised byte(s)
@@ -1154,13 +1154,21 @@ Syscall param clone(child_stack) contains uninitialised byte(s)
 Syscall param clone(parent_tidptr) contains uninitialised byte(s)
    ...
 
+Syscall param clone(parent_tidptr) points to unaddressable byte(s)
+   ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
 Syscall param clone(tlsinfo) contains uninitialised byte(s)
    ...
 
+Syscall param clone(tlsinfo) points to unaddressable byte(s)
+   ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
 Syscall param clone(child_tidptr) contains uninitialised byte(s)
    ...
 
-Syscall param clone(parent_tidptr) points to unaddressable byte(s)
+Syscall param clone(child_tidptr) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 -----------------------------------------------------