/* * Copyright (c) International Business Machines Corp., 2001 * Copyright (c) 2018 Xiao Yang * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. */ /* * DESCRIPTION * 1) Call sysctl(2) as a root user, and attempt to write data * to the kernel_table[]. Since the table does not have write * permissions even for the root, it should fail EPERM. * 2) Call sysctl(2) as a non-root user, and attempt to write data * to the kernel_table[]. Since the table does not have write * permission for the regular user, it should fail with EPERM. * * NOTE: There is a documentation bug in 2.6.33-rc1 where unfortunately * the behavior of sysctl(2) isn't properly documented, as discussed * in detail in the following thread: * http://sourceforge.net/mailarchive/message.php?msg_name=4B7BA24F.2010705%40linux.vnet.ibm.com. * * The documentation bug is filed as: * https://bugzilla.kernel.org/show_bug.cgi?id=15446 . If you want the * message removed, please ask your fellow kernel maintainer to fix their * documentation. * * Thanks! * -Ngie */ #include #include #include #include #include #include #include #include #include "tst_test.h" #include "lapi/syscalls.h" static int exp_eno; static void verify_sysctl(void) { char *osname = "Linux"; int name[] = {CTL_KERN, KERN_OSTYPE}; struct __sysctl_args args = { .name = name, .nlen = ARRAY_SIZE(name), .newval = osname, .newlen = sizeof(osname), }; TEST(tst_syscall(__NR__sysctl, &args)); if (TST_RET != -1) { tst_res(TFAIL, "sysctl(2) succeeded unexpectedly"); return; } if (TST_ERR == exp_eno) { tst_res(TPASS | TTERRNO, "Got expected error"); } else { tst_res(TFAIL | TTERRNO, "Got unexpected error, expected %s", tst_strerrno(exp_eno)); } } static void setup(void) { if ((tst_kvercmp(2, 6, 32)) <= 0) { exp_eno = EPERM; } else { /* Look above this warning. */ tst_res(TINFO, "this test's results are based on potentially undocumented behavior in the kernel. read the NOTE in the source file for more details"); exp_eno = EACCES; } } static void do_test(void) { pid_t pid; struct passwd *ltpuser; pid = SAFE_FORK(); if (!pid) { ltpuser = SAFE_GETPWNAM("nobody"); SAFE_SETUID(ltpuser->pw_uid); verify_sysctl(); } else { verify_sysctl(); tst_reap_children(); } } static struct tst_test test = { .needs_root = 1, .forks_child = 1, .setup = setup, .test_all = do_test, };