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