Fix false positive 'Conditional jump or move' on amd64 64 bits ptracing 32 bits.

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.
This commit is contained in:
Philippe Waroquiers 2019-01-12 15:08:59 +01:00
parent 3528f84037
commit d7d8231750
3 changed files with 25 additions and 8 deletions

2
NEWS
View File

@ -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)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View 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;

View 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
//----------------------------------------------------------------------