1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2020 Bernd Edlinger <bernd.edlinger@hotmail.de> 4 * All rights reserved. 5 * 6 * Check whether /proc/$pid/mem can be accessed without causing deadlocks 7 * when de_thread is blocked with ->cred_guard_mutex held. 8 */ 9 10 #include "../kselftest_harness.h" 11 #include <stdio.h> 12 #include <fcntl.h> 13 #include <pthread.h> 14 #include <signal.h> 15 #include <unistd.h> 16 #include <sys/ptrace.h> 17 18 static void *thread(void *arg) 19 { 20 ptrace(PTRACE_TRACEME, 0, 0L, 0L); 21 return NULL; 22 } 23 24 TEST(vmaccess) 25 { 26 int f, pid = fork(); 27 char mm[64]; 28 29 if (!pid) { 30 pthread_t pt; 31 32 pthread_create(&pt, NULL, thread, NULL); 33 pthread_join(pt, NULL); 34 execlp("true", "true", NULL); 35 } 36 37 sleep(1); 38 sprintf(mm, "/proc/%d/mem", pid); 39 f = open(mm, O_RDONLY); 40 ASSERT_GE(f, 0); 41 close(f); 42 f = kill(pid, SIGCONT); 43 ASSERT_EQ(f, 0); 44 } 45 46 TEST(attach) 47 { 48 int s, k, pid = fork(); 49 50 if (!pid) { 51 pthread_t pt; 52 53 pthread_create(&pt, NULL, thread, NULL); 54 pthread_join(pt, NULL); 55 execlp("sleep", "sleep", "2", NULL); 56 } 57 58 sleep(1); 59 k = ptrace(PTRACE_ATTACH, pid, 0L, 0L); 60 ASSERT_EQ(errno, EAGAIN); 61 ASSERT_EQ(k, -1); 62 k = waitpid(-1, &s, WNOHANG); 63 ASSERT_NE(k, -1); 64 ASSERT_NE(k, 0); 65 ASSERT_NE(k, pid); 66 ASSERT_EQ(WIFEXITED(s), 1); 67 ASSERT_EQ(WEXITSTATUS(s), 0); 68 sleep(1); 69 k = ptrace(PTRACE_ATTACH, pid, 0L, 0L); 70 ASSERT_EQ(k, 0); 71 k = waitpid(-1, &s, 0); 72 ASSERT_EQ(k, pid); 73 ASSERT_EQ(WIFSTOPPED(s), 1); 74 ASSERT_EQ(WSTOPSIG(s), SIGSTOP); 75 k = ptrace(PTRACE_DETACH, pid, 0L, 0L); 76 ASSERT_EQ(k, 0); 77 k = waitpid(-1, &s, 0); 78 ASSERT_EQ(k, pid); 79 ASSERT_EQ(WIFEXITED(s), 1); 80 ASSERT_EQ(WEXITSTATUS(s), 0); 81 k = waitpid(-1, NULL, 0); 82 ASSERT_EQ(k, -1); 83 ASSERT_EQ(errno, ECHILD); 84 } 85 86 TEST_HARNESS_MAIN 87