1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2019 Federico Bonfiglio <fedebonfi95@gmail.com>
4 * Copyright (c) Linux Test Project, 2019-2022
5 */
6
7/*\
8 * [Description]
9 *
10 * Test ioctl_ns with NS_GET_PARENT request.
11 *
12 * Parent process tries to get parent of initial namespace, which should
13 * fail with EPERM because it has no parent.
14 *
15 * Child process has a new pid namespace, which should make the call fail
16 * with EPERM error.
17 */
18
19#define _GNU_SOURCE
20
21#include <errno.h>
22#include <stdlib.h>
23#include "tst_test.h"
24#include "lapi/ioctl_ns.h"
25#include "lapi/sched.h"
26
27#define STACK_SIZE (1024 * 1024)
28
29static char *child_stack;
30
31static void setup(void)
32{
33	int exists = access("/proc/self/ns/pid", F_OK);
34
35	if (exists < 0)
36		tst_res(TCONF, "namespace not available");
37
38	child_stack = ltp_alloc_stack(STACK_SIZE);
39	if (!child_stack)
40		tst_brk(TBROK|TERRNO, "stack alloc");
41}
42
43static void cleanup(void)
44{
45	free(child_stack);
46}
47
48static void test_ns_get_parent(void)
49{
50	int fd, parent_fd;
51
52	fd = SAFE_OPEN("/proc/self/ns/pid", O_RDONLY);
53	parent_fd = ioctl(fd, NS_GET_PARENT);
54	if (parent_fd == -1) {
55		if (errno == ENOTTY)
56			tst_brk(TCONF, "ioctl(NS_GET_PARENT) not implemented");
57
58		if (errno == EPERM)
59			tst_res(TPASS, "NS_GET_PARENT fails with EPERM");
60		else
61			tst_res(TFAIL | TERRNO, "unexpected ioctl error");
62	} else {
63		tst_res(TFAIL, "call to ioctl succeded");
64	}
65	SAFE_CLOSE(fd);
66}
67
68static int child(void *arg LTP_ATTRIBUTE_UNUSED)
69{
70	test_ns_get_parent();
71	return 0;
72}
73
74static void run(void)
75{
76	test_ns_get_parent();
77
78	if (ltp_clone(CLONE_NEWPID | SIGCHLD, &child, 0,
79		STACK_SIZE, child_stack) == -1)
80		tst_brk(TBROK | TERRNO, "ltp_clone failed");
81}
82
83static struct tst_test test = {
84	.test_all = run,
85	.forks_child = 1,
86	.needs_root = 1,
87	.min_kver = "4.9",
88	.setup = setup,
89	.cleanup = cleanup,
90};
91