1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 4 */ 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <stdarg.h> 9 #include <unistd.h> 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <sched.h> 13 #include <signal.h> 14 #include <string.h> 15 #include <sys/mman.h> 16 #include <sys/stat.h> 17 #include <sys/wait.h> 18 #include <sys/time.h> 19 #include <sys/resource.h> 20 #include <asm/unistd.h> 21 #include <init.h> 22 #include <os.h> 23 #include <mem_user.h> 24 #include <ptrace_user.h> 25 #include <registers.h> 26 #include <skas.h> 27 28 static void ptrace_child(void) 29 { 30 int ret; 31 /* Calling os_getpid because some libcs cached getpid incorrectly */ 32 int pid = os_getpid(), ppid = getppid(); 33 int sc_result; 34 35 if (change_sig(SIGWINCH, 0) < 0 || 36 ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { 37 perror("ptrace"); 38 kill(pid, SIGKILL); 39 } 40 kill(pid, SIGSTOP); 41 42 /* 43 * This syscall will be intercepted by the parent. Don't call more than 44 * once, please. 45 */ 46 sc_result = os_getpid(); 47 48 if (sc_result == pid) 49 /* Nothing modified by the parent, we are running normally. */ 50 ret = 1; 51 else if (sc_result == ppid) 52 /* 53 * Expected in check_ptrace and check_sysemu when they succeed 54 * in modifying the stack frame 55 */ 56 ret = 0; 57 else 58 /* Serious trouble! This could be caused by a bug in host 2.6 59 * SKAS3/2.6 patch before release -V6, together with a bug in 60 * the UML code itself. 61 */ 62 ret = 2; 63 64 exit(ret); 65 } 66 67 static void fatal_perror(const char *str) 68 { 69 perror(str); 70 exit(1); 71 } 72 73 static void fatal(char *fmt, ...) 74 { 75 va_list list; 76 77 va_start(list, fmt); 78 vfprintf(stderr, fmt, list); 79 va_end(list); 80 81 exit(1); 82 } 83 84 static void non_fatal(char *fmt, ...) 85 { 86 va_list list; 87 88 va_start(list, fmt); 89 vfprintf(stderr, fmt, list); 90 va_end(list); 91 } 92 93 static int start_ptraced_child(void) 94 { 95 int pid, n, status; 96 97 fflush(stdout); 98 99 pid = fork(); 100 if (pid == 0) 101 ptrace_child(); 102 else if (pid < 0) 103 fatal_perror("start_ptraced_child : fork failed"); 104 105 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 106 if (n < 0) 107 fatal_perror("check_ptrace : waitpid failed"); 108 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 109 fatal("check_ptrace : expected SIGSTOP, got status = %d", 110 status); 111 112 return pid; 113 } 114 115 /* When testing for SYSEMU support, if it is one of the broken versions, we 116 * must just avoid using sysemu, not panic, but only if SYSEMU features are 117 * broken. 118 * So only for SYSEMU features we test mustpanic, while normal host features 119 * must work anyway! 120 */ 121 static int stop_ptraced_child(int pid, int exitcode, int mustexit) 122 { 123 int status, n, ret = 0; 124 125 if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) { 126 perror("stop_ptraced_child : ptrace failed"); 127 return -1; 128 } 129 CATCH_EINTR(n = waitpid(pid, &status, 0)); 130 if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 131 int exit_with = WEXITSTATUS(status); 132 if (exit_with == 2) 133 non_fatal("check_ptrace : child exited with status 2. " 134 "\nDisabling SYSEMU support.\n"); 135 non_fatal("check_ptrace : child exited with exitcode %d, while " 136 "expecting %d; status 0x%x\n", exit_with, 137 exitcode, status); 138 if (mustexit) 139 exit(1); 140 ret = -1; 141 } 142 143 return ret; 144 } 145 146 static void __init check_sysemu(void) 147 { 148 int pid, n, status, count=0; 149 150 os_info("Checking syscall emulation for ptrace..."); 151 pid = start_ptraced_child(); 152 153 if ((ptrace(PTRACE_SETOPTIONS, pid, 0, 154 (void *) PTRACE_O_TRACESYSGOOD) < 0)) 155 fatal_perror("check_sysemu: PTRACE_SETOPTIONS failed"); 156 157 while (1) { 158 count++; 159 if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) 160 goto fail; 161 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 162 if (n < 0) 163 fatal_perror("check_sysemu: wait failed"); 164 165 if (WIFSTOPPED(status) && 166 (WSTOPSIG(status) == (SIGTRAP|0x80))) { 167 if (!count) { 168 non_fatal("check_sysemu: SYSEMU_SINGLESTEP " 169 "doesn't singlestep"); 170 goto fail; 171 } 172 n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, 173 os_getpid()); 174 if (n < 0) 175 fatal_perror("check_sysemu : failed to modify " 176 "system call return"); 177 break; 178 } 179 else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) 180 count++; 181 else { 182 non_fatal("check_sysemu: expected SIGTRAP or " 183 "(SIGTRAP | 0x80), got status = %d\n", 184 status); 185 goto fail; 186 } 187 } 188 if (stop_ptraced_child(pid, 0, 0) < 0) 189 goto fail_stopped; 190 191 os_info("OK\n"); 192 193 return; 194 195 fail: 196 stop_ptraced_child(pid, 1, 0); 197 fail_stopped: 198 fatal("missing\n"); 199 } 200 201 static void __init check_ptrace(void) 202 { 203 int pid, syscall, n, status; 204 205 os_info("Checking that ptrace can change system call numbers..."); 206 pid = start_ptraced_child(); 207 208 if ((ptrace(PTRACE_SETOPTIONS, pid, 0, 209 (void *) PTRACE_O_TRACESYSGOOD) < 0)) 210 fatal_perror("check_ptrace: PTRACE_SETOPTIONS failed"); 211 212 while (1) { 213 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) 214 fatal_perror("check_ptrace : ptrace failed"); 215 216 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 217 if (n < 0) 218 fatal_perror("check_ptrace : wait failed"); 219 220 if (!WIFSTOPPED(status) || 221 (WSTOPSIG(status) != (SIGTRAP | 0x80))) 222 fatal("check_ptrace : expected (SIGTRAP|0x80), " 223 "got status = %d", status); 224 225 syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 226 0); 227 if (syscall == __NR_getpid) { 228 n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 229 __NR_getppid); 230 if (n < 0) 231 fatal_perror("check_ptrace : failed to modify " 232 "system call"); 233 break; 234 } 235 } 236 stop_ptraced_child(pid, 0, 1); 237 os_info("OK\n"); 238 check_sysemu(); 239 } 240 241 extern void check_tmpexec(void); 242 243 static void __init check_coredump_limit(void) 244 { 245 struct rlimit lim; 246 int err = getrlimit(RLIMIT_CORE, &lim); 247 248 if (err) { 249 perror("Getting core dump limit"); 250 return; 251 } 252 253 os_info("Core dump limits :\n\tsoft - "); 254 if (lim.rlim_cur == RLIM_INFINITY) 255 os_info("NONE\n"); 256 else 257 os_info("%llu\n", (unsigned long long)lim.rlim_cur); 258 259 os_info("\thard - "); 260 if (lim.rlim_max == RLIM_INFINITY) 261 os_info("NONE\n"); 262 else 263 os_info("%llu\n", (unsigned long long)lim.rlim_max); 264 } 265 266 void __init get_host_cpu_features( 267 void (*flags_helper_func)(char *line), 268 void (*cache_helper_func)(char *line)) 269 { 270 FILE *cpuinfo; 271 char *line = NULL; 272 size_t len = 0; 273 int done_parsing = 0; 274 275 cpuinfo = fopen("/proc/cpuinfo", "r"); 276 if (cpuinfo == NULL) { 277 os_info("Failed to get host CPU features\n"); 278 } else { 279 while ((getline(&line, &len, cpuinfo)) != -1) { 280 if (strstr(line, "flags")) { 281 flags_helper_func(line); 282 done_parsing++; 283 } 284 if (strstr(line, "cache_alignment")) { 285 cache_helper_func(line); 286 done_parsing++; 287 } 288 free(line); 289 line = NULL; 290 if (done_parsing > 1) 291 break; 292 } 293 fclose(cpuinfo); 294 } 295 } 296 297 298 void __init os_early_checks(void) 299 { 300 int pid; 301 302 /* Print out the core dump limits early */ 303 check_coredump_limit(); 304 305 check_ptrace(); 306 307 /* Need to check this early because mmapping happens before the 308 * kernel is running. 309 */ 310 check_tmpexec(); 311 312 pid = start_ptraced_child(); 313 if (init_pid_registers(pid)) 314 fatal("Failed to initialize default registers"); 315 stop_ptraced_child(pid, 1, 1); 316 } 317 318 int __init parse_iomem(char *str, int *add) 319 { 320 struct iomem_region *new; 321 struct stat64 buf; 322 char *file, *driver; 323 int fd, size; 324 325 driver = str; 326 file = strchr(str,','); 327 if (file == NULL) { 328 os_warn("parse_iomem : failed to parse iomem\n"); 329 goto out; 330 } 331 *file = '\0'; 332 file++; 333 fd = open(file, O_RDWR, 0); 334 if (fd < 0) { 335 perror("parse_iomem - Couldn't open io file"); 336 goto out; 337 } 338 339 if (fstat64(fd, &buf) < 0) { 340 perror("parse_iomem - cannot stat_fd file"); 341 goto out_close; 342 } 343 344 new = malloc(sizeof(*new)); 345 if (new == NULL) { 346 perror("Couldn't allocate iomem_region struct"); 347 goto out_close; 348 } 349 350 size = (buf.st_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1); 351 352 *new = ((struct iomem_region) { .next = iomem_regions, 353 .driver = driver, 354 .fd = fd, 355 .size = size, 356 .phys = 0, 357 .virt = 0 }); 358 iomem_regions = new; 359 iomem_size += new->size + UM_KERN_PAGE_SIZE; 360 361 return 0; 362 out_close: 363 close(fd); 364 out: 365 return 1; 366 } 367