]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix false positive 'Conditional jump or move' on amd64 64 bits ptracing 32 bits.
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 12 Jan 2019 14:08:59 +0000 (15:08 +0100)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 12 Jan 2019 14:35:59 +0000 (15:35 +0100)
PTRACE_GET_THREAD_AREA is not handled by amd64 linux syswrap, which leads
to false positive errors in 64 bits program ptrace-ing 32 bits processes.

For example, the below error was wrongly reported on GDB:
==25377== Conditional jump or move depends on uninitialised value(s)
==25377==    at 0x8A1D7EC: td_thr_get_info (td_thr_get_info.c:35)
==25377==    by 0x526819: thread_from_lwp(thread_info*, ptid_t) (linux-thread-db.c:417)
==25377==    by 0x5281D4: thread_db_notice_clone(ptid_t, ptid_t) (linux-thread-db.c:442)
==25377==    by 0x51773B: linux_handle_extended_wait(lwp_info*, int) (linux-nat.c:2027)
....
==25377==  Uninitialised value was created by a stack allocation
==25377==    at 0x69A360: x86_linux_get_thread_area(int, void*, unsigned int*) (x86-linux-nat.c:278)

Fix this by implementing PTRACE_GET|SET_THREAD_AREA on amd64.

NEWS
coregrind/m_syswrap/syswrap-amd64-linux.c
include/vki/vki-amd64-linux.h

diff --git a/NEWS b/NEWS
index 2d1f2e99b9cbbab8d367bf5d072e21a13f369755..6ff9464238f1cd3c99d3ace78442366b90757726 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -86,6 +86,8 @@ where XXXXXX is the bug number as listed below.
 402515  Implement new option --show-error-list=no|yes / -s
 402519  POWER 3.0 addex instruction incorrectly implemented
 
+n-i-bz  add syswrap for PTRACE_GET|SET_THREAD_AREA on amd64.
+
 Release 3.14.0 (9 October 2018)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index 60fb5ffc0839b3ed8f56609bff292269b159afe6..30e7d0e910fb19344cda4f662ab40fc08b58f226 100644 (file)
@@ -322,6 +322,10 @@ PRE(sys_ptrace)
       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 
                     sizeof (struct vki_user_i387_struct));
       break;
+   case VKI_PTRACE_GET_THREAD_AREA:
+      PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, 
+                     sizeof(struct vki_user_desc) );
+      break;
    case VKI_PTRACE_SETREGS:
       PRE_MEM_READ( "ptrace(setregs)", ARG4, 
                     sizeof (struct vki_user_regs_struct));
@@ -330,6 +334,10 @@ PRE(sys_ptrace)
       PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 
                     sizeof (struct vki_user_i387_struct));
       break;
+   case VKI_PTRACE_SET_THREAD_AREA:
+      PRE_MEM_READ( "ptrace(set_thread_area)", ARG4, 
+                     sizeof(struct vki_user_desc) );
+      break;
    case VKI_PTRACE_GETEVENTMSG:
       PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
       break;
@@ -367,6 +375,9 @@ POST(sys_ptrace)
    case VKI_PTRACE_GETFPREGS:
       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
       break;
+   case VKI_PTRACE_GET_THREAD_AREA:
+      POST_MEM_WRITE( ARG4, sizeof(struct vki_user_desc) );
+      break;
    case VKI_PTRACE_GETEVENTMSG:
       POST_MEM_WRITE( ARG4, sizeof(unsigned long));
       break;
index a506ade06c6a184700a0b8a94295b5d30b9e0c95..f99dcf81cf8727721135d8838f6c064f15de8a6d 100644 (file)
@@ -559,16 +559,15 @@ struct vki_ucontext {
 #define VKI_ARCH_GET_GS 0x1004
 
 //----------------------------------------------------------------------
-// From linux-2.6.9/include/asm-x86_64/ldt.h
+// Originally from linux-2.6.9/include/asm-x86_64/ldt.h
 //----------------------------------------------------------------------
 
-// I think this LDT stuff will have to be reinstated for amd64, but I'm not
-// certain.  (Nb: The sys_arch_prctl seems to have replaced
-// [gs]et_thread_area syscalls.)
-//
 // Note that the type here is very slightly different to the
-// type for x86 (the final 'lm' field is added);  I'm not sure about the
-// significance of that... --njn
+// type for x86 (the final 'lm' field is added).
+/* The explanation is: the final bit is not present in 32 bit code running
+   on 64 bits kernel. The kernel has to assume this value is 0 whenever
+   user_desc arrives from a 32-bit program.
+   See /usr/include/asm/ldt.h. */
 
 /* [[Nb: This is the structure passed to the modify_ldt syscall.  Just so as
    to confuse and annoy everyone, this is _not_ the same as an
@@ -579,7 +578,7 @@ struct vki_ucontext {
    is rather for 32bit. */
 struct vki_user_desc {
        unsigned int  entry_number;
-       unsigned long base_addr;
+       unsigned int  base_addr;
        unsigned int  limit;
        unsigned int  seg_32bit:1;
        unsigned int  contents:2;
@@ -683,6 +682,11 @@ struct vki_shminfo64 {
 #define VKI_PTRACE_GETFPREGS          14
 #define VKI_PTRACE_SETFPREGS          15
 
+// From /usr/include/asm/ptrace-abit.h
+/* only useful for access 32bit programs / kernels */
+#define VKI_PTRACE_GET_THREAD_AREA    25
+#define VKI_PTRACE_SET_THREAD_AREA    26
+
 //----------------------------------------------------------------------
 // From linux-2.6.8.1/include/asm-generic/errno.h
 //----------------------------------------------------------------------