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