1c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//===-- sanitizer_linux_s390.cc -------------------------------------------===// 2c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 3c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// The LLVM Compiler Infrastructure 4c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 5c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 6c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// License. See LICENSE.TXT for details. 7c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 8c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 9c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// 10c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// This file is shared between AddressSanitizer and ThreadSanitizer 11c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// run-time libraries and implements s390-linux-specific functions from 12c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// sanitizer_libc.h. 13c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 14c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 15c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include "sanitizer_platform.h" 16c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 17c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_LINUX && SANITIZER_S390 18c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 19c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include "sanitizer_libc.h" 20c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include "sanitizer_linux.h" 21c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 22c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <errno.h> 23c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <sys/syscall.h> 24c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <sys/utsname.h> 25c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <unistd.h> 26c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 27c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarnamespace __sanitizer { 28c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 29c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// --------------- sanitizer_libc.h 30c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainaruptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, 31c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar OFF_T offset) { 32c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar struct s390_mmap_params { 33c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar unsigned long addr; 34c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar unsigned long length; 35c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar unsigned long prot; 36c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar unsigned long flags; 37c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar unsigned long fd; 38c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar unsigned long offset; 39c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } params = { 40c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar (unsigned long)addr, 41c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar (unsigned long)length, 42c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar (unsigned long)prot, 43c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar (unsigned long)flags, 44c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar (unsigned long)fd, 45c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar# ifdef __s390x__ 46c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar (unsigned long)offset, 47c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar# else 48c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar (unsigned long)(offset / 4096), 49c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar# endif 50c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar }; 51c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar# ifdef __s390x__ 52c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return syscall(__NR_mmap, ¶ms); 53c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar# else 54c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return syscall(__NR_mmap2, ¶ms); 55c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar# endif 56c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 57c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 58c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainaruptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, 59c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar int *parent_tidptr, void *newtls, int *child_tidptr) { 60c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (!fn || !child_stack) 61c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return -EINVAL; 62c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar CHECK_EQ(0, (uptr)child_stack % 16); 63c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Minimum frame size. 64c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef __s390x__ 65c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar child_stack = (char *)child_stack - 160; 66c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else 67c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar child_stack = (char *)child_stack - 96; 68c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 69c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Terminate unwind chain. 70c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar ((unsigned long *)child_stack)[0] = 0; 71c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // And pass parameters. 72c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar ((unsigned long *)child_stack)[1] = (uptr)fn; 73c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar ((unsigned long *)child_stack)[2] = (uptr)arg; 74c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar register long res __asm__("r2"); 75c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar register void *__cstack __asm__("r2") = child_stack; 76c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar register int __flags __asm__("r3") = flags; 77c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar register int * __ptidptr __asm__("r4") = parent_tidptr; 78c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar register int * __ctidptr __asm__("r5") = child_tidptr; 79c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar register void * __newtls __asm__("r6") = newtls; 80c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 81c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar __asm__ __volatile__( 82c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar /* Clone. */ 83c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "svc %1\n" 84c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 85c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar /* if (%r2 != 0) 86c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar * return; 87c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar */ 88c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef __s390x__ 89c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "cghi %%r2, 0\n" 90c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else 91c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "chi %%r2, 0\n" 92c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 93c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "jne 1f\n" 94c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 95c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar /* Call "fn(arg)". */ 96c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef __s390x__ 97c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "lmg %%r1, %%r2, 8(%%r15)\n" 98c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else 99c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "lm %%r1, %%r2, 4(%%r15)\n" 100c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 101c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "basr %%r14, %%r1\n" 102c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 103c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar /* Call _exit(%r2). */ 104c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "svc %2\n" 105c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 106c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar /* Return to parent. */ 107c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "1:\n" 108c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar : "=r" (res) 109c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar : "i"(__NR_clone), "i"(__NR_exit), 110c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "r"(__cstack), 111c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "r"(__flags), 112c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "r"(__ptidptr), 113c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "r"(__ctidptr), 114c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "r"(__newtls) 115c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar : "memory", "cc"); 116c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return res; 117c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 118c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 119c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_S390_64 120c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic bool FixedCVE_2016_2143() { 121c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Try to determine if the running kernel has a fix for CVE-2016-2143, 122c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // return false if in doubt (better safe than sorry). Distros may want to 123c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // adjust this for their own kernels. 124c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar struct utsname buf; 125c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar unsigned int major, minor, patch = 0; 126c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // This should never fail, but just in case... 127c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (uname(&buf)) 128c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 129c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar char *ptr = buf.release; 130c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar major = internal_simple_strtoll(ptr, &ptr, 10); 131c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // At least first 2 should be matched. 132c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (ptr[0] != '.') 133c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 134c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar minor = internal_simple_strtoll(ptr+1, &ptr, 10); 135c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Third is optional. 136c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (ptr[0] == '.') 137c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar patch = internal_simple_strtoll(ptr+1, &ptr, 10); 138c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (major < 3) { 139c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // <3.0 is bad. 140c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 141c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } else if (major == 3) { 142c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // 3.2.79+ is OK. 143c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (minor == 2 && patch >= 79) 144c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 145c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // 3.12.58+ is OK. 146c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (minor == 12 && patch >= 58) 147c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 148c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Otherwise, bad. 149c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return false; 150c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } else if (major == 4) { 151c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // 4.1.21+ is OK. 152c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (minor == 1 && patch >= 21) 153c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 154c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // 4.4.6+ is OK. 155c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (minor == 4 && patch >= 6) 156c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 157c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Otherwise, OK if 4.5+. 158c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return minor >= 5; 159c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } else { 160c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Linux 5 and up are fine. 161c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return true; 162c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 163c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 164c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 165c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid AvoidCVE_2016_2143() { 166c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Older kernels are affected by CVE-2016-2143 - they will crash hard 167c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // if someone uses 4-level page tables (ie. virtual addresses >= 4TB) 168c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // and fork() in the same process. Unfortunately, sanitizers tend to 169c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // require such addresses. Since this is very likely to crash the whole 170c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // machine (sanitizers themselves use fork() for llvm-symbolizer, for one), 171c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // abort the process at initialization instead. 172c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (FixedCVE_2016_2143()) 173c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return; 174c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (GetEnv("SANITIZER_IGNORE_CVE_2016_2143")) 175c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return; 176c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Report( 177c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "ERROR: Your kernel seems to be vulnerable to CVE-2016-2143. Using ASan,\n" 178c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "MSan, TSan, DFSan or LSan with such kernel can and will crash your\n" 179c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "machine, or worse.\n" 180c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "\n" 181c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "If you are certain your kernel is not vulnerable (you have compiled it\n" 182c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "yourself, or are using an unrecognized distribution kernel), you can\n" 183c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "override this safety check by exporting SANITIZER_IGNORE_CVE_2016_2143\n" 184c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "with any value.\n"); 185c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Die(); 186c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 187c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 188c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 189c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} // namespace __sanitizer 190c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 191c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif // SANITIZER_LINUX && SANITIZER_S390 192