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