• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2024 FUJITSU LIMITED. All Rights Reserved.
4  * Copyright (c) Linux Test Project, 2024
5  * Author: Ma Xinjian <maxj.fnst@fujitsu.com>
6  */
7 
8 /*\
9  * [Description]
10  *
11  * Verify that getcpu(2) fails with EFAULT if cpu_id or node_id points outside
12  * the calling process address space.
13  */
14 
15 #define _GNU_SOURCE
16 
17 #include "tst_test.h"
18 #include "lapi/sched.h"
19 
20 static unsigned int cpu_id, node_id;
21 
22 static struct tcase {
23 	unsigned int *cpu_id;
24 	unsigned int *node_id;
25 	char *desc;
26 } tcases[] = {
27 	{NULL, &node_id, "cpu_id"},
28 	{&cpu_id, NULL, "node_id"},
29 };
30 
check_getcpu(unsigned int n)31 static void check_getcpu(unsigned int n)
32 {
33 	struct tcase *tc = &tcases[n];
34 	int status;
35 	pid_t pid;
36 
37 	tst_res(TINFO, "Test %s outside process address space", tc->desc);
38 
39 	if (!tc->cpu_id)
40 		tc->cpu_id = tst_get_bad_addr(NULL);
41 
42 	if (!tc->node_id)
43 		tc->node_id = tst_get_bad_addr(NULL);
44 
45 	pid = SAFE_FORK();
46 	if (!pid) {
47 		TST_EXP_FAIL(getcpu(tc->cpu_id, tc->node_id), EFAULT);
48 
49 		exit(0);
50 	}
51 
52 	SAFE_WAITPID(pid, &status, 0);
53 
54 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
55 		tst_res(TPASS, "getcpu() caused SIGSEGV");
56 		return;
57 	}
58 
59 	if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
60 		return;
61 
62 	tst_res(TFAIL, "child %s", tst_strstatus(status));
63 }
64 
65 static struct tst_test test = {
66 	.test = check_getcpu,
67 	.tcnt = ARRAY_SIZE(tcases),
68 	.forks_child = 1,
69 };
70