xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/ptrace/ptrace03.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
4  *
5  * AUTHOR: Saji Kumar.V.R <[email protected]>
6  *
7  * 1) ptrace() returns -1 and sets errno to ESRCH if process with
8  * specified pid does not exist.
9  * 2) ptrace() returns -1 and sets errno to EPERM if we are trying
10  * to trace a process which is already been traced
11  */
12 
13 #include <errno.h>
14 #include <signal.h>
15 #include <sys/wait.h>
16 #include <pwd.h>
17 #include <stdlib.h>
18 #include <sys/ptrace.h>
19 #include "tst_test.h"
20 
21 static pid_t unused_pid;
22 static pid_t zero_pid;
23 
24 static struct tcase {
25 	int request;
26 	pid_t *pid;
27 	int exp_errno;
28 	char *tname;
29 } tcases[] = {
30 	{PTRACE_ATTACH, &unused_pid, ESRCH,
31 	"Trace a process which does not exist"},
32 
33 	{PTRACE_TRACEME, &zero_pid, EPERM,
34 	"Trace a process which is already been traced"}
35 };
36 
verify_ptrace(unsigned int n)37 static void verify_ptrace(unsigned int n)
38 {
39 	struct tcase *tc = &tcases[n];
40 	int child_pid;
41 
42 	tst_res(TINFO, "%s", tc->tname);
43 
44 	child_pid = SAFE_FORK();
45 	if (!child_pid) {
46 		if (tc->exp_errno == EPERM)
47 			SAFE_PTRACE(PTRACE_TRACEME, 0, NULL, NULL);
48 
49 		TEST(ptrace(tc->request, *(tc->pid), NULL, NULL));
50 		if (TST_RET == 0) {
51 			tst_res(TFAIL, "ptrace() succeeded unexpectedly");
52 			exit(1);
53 		}
54 		if (tc->exp_errno == TST_ERR)
55 			tst_res(TPASS | TTERRNO, "ptrace() failed as expected");
56 		else
57 			tst_res(TFAIL | TTERRNO, "ptrace() failed unexpectedly, expected %s",
58 					tst_strerrno(tc->exp_errno));
59 	}
60 	tst_reap_children();
61 }
62 
setup(void)63 static void setup(void)
64 {
65 	unused_pid = tst_get_unused_pid();
66 }
67 
68 static struct tst_test test = {
69 	.test = verify_ptrace,
70 	.tcnt = ARRAY_SIZE(tcases),
71 	.setup = setup,
72 	.forks_child = 1,
73 };
74