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