// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2020 Bernd Edlinger <bernd.edlinger@hotmail.de> * All rights reserved. * * Check whether /proc/$pid/mem can be accessed without causing deadlocks * when de_thread is blocked with ->cred_guard_mutex held. */ #include "../kselftest_harness.h" #include <stdio.h> #include <fcntl.h> #include <pthread.h> #include <signal.h> #include <unistd.h> #include <sys/ptrace.h> static void *thread(void *arg) { ptrace(PTRACE_TRACEME, 0, 0L, 0L); return NULL; } TEST(vmaccess) { int f, pid = fork(); char mm[64]; if (!pid) { pthread_t pt; pthread_create(&pt, NULL, thread, NULL); pthread_join(pt, NULL); execlp("true", "true", NULL); } sleep(1); sprintf(mm, "/proc/%d/mem", pid); f = open(mm, O_RDONLY); ASSERT_GE(f, 0); close(f); f = kill(pid, SIGCONT); ASSERT_EQ(f, 0); } TEST(attach) { int s, k, pid = fork(); if (!pid) { pthread_t pt; pthread_create(&pt, NULL, thread, NULL); pthread_join(pt, NULL); execlp("sleep", "sleep", "2", NULL); } sleep(1); k = ptrace(PTRACE_ATTACH, pid, 0L, 0L); ASSERT_EQ(errno, EAGAIN); ASSERT_EQ(k, -1); k = waitpid(-1, &s, WNOHANG); ASSERT_NE(k, -1); ASSERT_NE(k, 0); ASSERT_NE(k, pid); ASSERT_EQ(WIFEXITED(s), 1); ASSERT_EQ(WEXITSTATUS(s), 0); sleep(1); k = ptrace(PTRACE_ATTACH, pid, 0L, 0L); ASSERT_EQ(k, 0); k = waitpid(-1, &s, 0); ASSERT_EQ(k, pid); ASSERT_EQ(WIFSTOPPED(s), 1); ASSERT_EQ(WSTOPSIG(s), SIGSTOP); k = ptrace(PTRACE_DETACH, pid, 0L, 0L); ASSERT_EQ(k, 0); k = waitpid(-1, &s, 0); ASSERT_EQ(k, pid); ASSERT_EQ(WIFEXITED(s), 1); ASSERT_EQ(WEXITSTATUS(s), 0); k = waitpid(-1, NULL, 0); ASSERT_EQ(k, -1); ASSERT_EQ(errno, ECHILD); } TEST_HARNESS_MAIN