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