diff --git a/NEWS b/NEWS index c79e9f36d..d0c1d43f3 100644 --- a/NEWS +++ b/NEWS @@ -185,6 +185,7 @@ where XXXXXX is the bug number as listed below. 369360 Bad sigprocmask old or new sets can crash valgrind 369361 vmsplice syscall wrapper crashes on bad iovec 369362 Bad sigaction arguments crash valgrind +369383 x86 sys_modify_ldt wrapper crashes on bad ptr n-i-bz Fix incorrect (or infinite loop) unwind on RHEL7 x86 and amd64 n-i-bz massif --pages-as-heap=yes does not report peak caused by mmap+munmap diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 0c986cba3..0d8ff4576 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -596,24 +596,31 @@ SysRes write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode ) static SysRes sys_modify_ldt ( ThreadId tid, Int func, void* ptr, UInt bytecount ) { - SysRes ret = VG_(mk_SysRes_Error)( VKI_ENOSYS ); + SysRes ret; - switch (func) { - case 0: - ret = read_ldt(tid, ptr, bytecount); - break; - case 1: - ret = write_ldt(tid, ptr, bytecount, 1); - break; - case 2: - VG_(unimplemented)("sys_modify_ldt: func == 2"); - /* god knows what this is about */ - /* ret = read_default_ldt(ptr, bytecount); */ - /*UNREACHED*/ - break; - case 0x11: - ret = write_ldt(tid, ptr, bytecount, 0); - break; + if (func != 0 && func != 1 && func != 2 && func != 0x11) { + ret = VG_(mk_SysRes_Error)( VKI_ENOSYS ); + } else if (ptr != NULL && ! ML_(safe_to_deref)(ptr, bytecount)) { + ret = VG_(mk_SysRes_Error)( VKI_EFAULT ); + } else { + switch (func) { + case 0: + ret = read_ldt(tid, ptr, bytecount); + break; + case 1: + ret = write_ldt(tid, ptr, bytecount, 1); + break; + case 2: + ret = VG_(mk_SysRes_Error)( VKI_ENOSYS ); + VG_(unimplemented)("sys_modify_ldt: func == 2"); + /* god knows what this is about */ + /* ret = read_default_ldt(ptr, bytecount); */ + /*UNREACHED*/ + break; + case 0x11: + ret = write_ldt(tid, ptr, bytecount, 0); + break; + } } return ret; }