1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001
4f08c3bdfSopenharmony_ci * Copyright (c) 2018 Xiao Yang <yangx.jy@cn.fujitsu.com>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*
8f08c3bdfSopenharmony_ci * DESCRIPTION
9f08c3bdfSopenharmony_ci * 1) Call sysctl(2) as a root user, and attempt to write data
10f08c3bdfSopenharmony_ci *    to the kernel_table[]. Since the table does not have write
11f08c3bdfSopenharmony_ci *    permissions even for the root, it should fail EPERM.
12f08c3bdfSopenharmony_ci * 2) Call sysctl(2) as a non-root user, and attempt to write data
13f08c3bdfSopenharmony_ci *    to the kernel_table[]. Since the table does not have write
14f08c3bdfSopenharmony_ci *    permission for the regular user, it should fail with EPERM.
15f08c3bdfSopenharmony_ci *
16f08c3bdfSopenharmony_ci * NOTE: There is a documentation bug in 2.6.33-rc1 where unfortunately
17f08c3bdfSopenharmony_ci * the behavior of sysctl(2) isn't properly documented, as discussed
18f08c3bdfSopenharmony_ci * in detail in the following thread:
19f08c3bdfSopenharmony_ci * http://sourceforge.net/mailarchive/message.php?msg_name=4B7BA24F.2010705%40linux.vnet.ibm.com.
20f08c3bdfSopenharmony_ci *
21f08c3bdfSopenharmony_ci * The documentation bug is filed as:
22f08c3bdfSopenharmony_ci * https://bugzilla.kernel.org/show_bug.cgi?id=15446 . If you want the
23f08c3bdfSopenharmony_ci * message removed, please ask your fellow kernel maintainer to fix their
24f08c3bdfSopenharmony_ci * documentation.
25f08c3bdfSopenharmony_ci *
26f08c3bdfSopenharmony_ci * Thanks!
27f08c3bdfSopenharmony_ci * -Ngie
28f08c3bdfSopenharmony_ci */
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci#include <sys/types.h>
31f08c3bdfSopenharmony_ci#include <sys/wait.h>
32f08c3bdfSopenharmony_ci#include <stdio.h>
33f08c3bdfSopenharmony_ci#include <errno.h>
34f08c3bdfSopenharmony_ci#include <unistd.h>
35f08c3bdfSopenharmony_ci#include <linux/unistd.h>
36f08c3bdfSopenharmony_ci#include <linux/sysctl.h>
37f08c3bdfSopenharmony_ci#include <pwd.h>
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci#include "tst_test.h"
40f08c3bdfSopenharmony_ci#include "lapi/syscalls.h"
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_cistatic int exp_eno;
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_cistatic void verify_sysctl(void)
45f08c3bdfSopenharmony_ci{
46f08c3bdfSopenharmony_ci	char *osname = "Linux";
47f08c3bdfSopenharmony_ci	int name[] = {CTL_KERN, KERN_OSTYPE};
48f08c3bdfSopenharmony_ci	struct __sysctl_args args = {
49f08c3bdfSopenharmony_ci		.name = name,
50f08c3bdfSopenharmony_ci		.nlen = ARRAY_SIZE(name),
51f08c3bdfSopenharmony_ci		.newval = osname,
52f08c3bdfSopenharmony_ci		.newlen = sizeof(osname),
53f08c3bdfSopenharmony_ci	};
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_ci	TEST(tst_syscall(__NR__sysctl, &args));
56f08c3bdfSopenharmony_ci	if (TST_RET != -1) {
57f08c3bdfSopenharmony_ci		tst_res(TFAIL, "sysctl(2) succeeded unexpectedly");
58f08c3bdfSopenharmony_ci		return;
59f08c3bdfSopenharmony_ci	}
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ci	if (TST_ERR == exp_eno) {
62f08c3bdfSopenharmony_ci		tst_res(TPASS | TTERRNO, "Got expected error");
63f08c3bdfSopenharmony_ci	} else {
64f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "Got unexpected error, expected %s",
65f08c3bdfSopenharmony_ci			tst_strerrno(exp_eno));
66f08c3bdfSopenharmony_ci	}
67f08c3bdfSopenharmony_ci}
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_cistatic void setup(void)
70f08c3bdfSopenharmony_ci{
71f08c3bdfSopenharmony_ci	/* Look above this warning. */
72f08c3bdfSopenharmony_ci	tst_res(TINFO,
73f08c3bdfSopenharmony_ci		 "this test's results are based on potentially undocumented behavior in the kernel. read the NOTE in the source file for more details");
74f08c3bdfSopenharmony_ci	exp_eno = EACCES;
75f08c3bdfSopenharmony_ci}
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_cistatic void do_test(void)
78f08c3bdfSopenharmony_ci{
79f08c3bdfSopenharmony_ci	pid_t pid;
80f08c3bdfSopenharmony_ci	struct passwd *ltpuser;
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	pid = SAFE_FORK();
83f08c3bdfSopenharmony_ci	if (!pid) {
84f08c3bdfSopenharmony_ci		ltpuser = SAFE_GETPWNAM("nobody");
85f08c3bdfSopenharmony_ci		SAFE_SETUID(ltpuser->pw_uid);
86f08c3bdfSopenharmony_ci		verify_sysctl();
87f08c3bdfSopenharmony_ci	} else {
88f08c3bdfSopenharmony_ci		verify_sysctl();
89f08c3bdfSopenharmony_ci		tst_reap_children();
90f08c3bdfSopenharmony_ci	}
91f08c3bdfSopenharmony_ci}
92f08c3bdfSopenharmony_ci
93f08c3bdfSopenharmony_cistatic struct tst_test test = {
94f08c3bdfSopenharmony_ci	.needs_root = 1,
95f08c3bdfSopenharmony_ci	.forks_child = 1,
96f08c3bdfSopenharmony_ci	.setup = setup,
97f08c3bdfSopenharmony_ci	.test_all = do_test,
98f08c3bdfSopenharmony_ci};
99