Skip to content

Commit 2de4e82

Browse files
bernd-edlingerebiederm
authored andcommitted
selftests/ptrace: add test cases for dead-locks
This adds test cases for ptrace deadlocks. Additionally fixes a compile problem in get_syscall_info.c, observed with gcc-4.8.4: get_syscall_info.c: In function 'get_syscall_info': get_syscall_info.c:93:3: error: 'for' loop initial declarations are only allowed in C99 mode for (unsigned int i = 0; i < ARRAY_SIZE(args); ++i) { ^ get_syscall_info.c:93:3: note: use option -std=c99 or -std=gnu99 to compile your code Signed-off-by: Bernd Edlinger <[email protected]> Reviewed-by: Kees Cook <[email protected]> Signed-off-by: Eric W. Biederman <[email protected]>
1 parent 3e74fab commit 2de4e82

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0-only
2-
CFLAGS += -iquote../../../../include/uapi -Wall
2+
CFLAGS += -std=c99 -pthread -iquote../../../../include/uapi -Wall
33

4-
TEST_GEN_PROGS := get_syscall_info peeksiginfo
4+
TEST_GEN_PROGS := get_syscall_info peeksiginfo vmaccess
55

66
include ../lib.mk
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* Copyright (c) 2020 Bernd Edlinger <[email protected]>
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

0 commit comments

Comments
 (0)