1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) International Business Machines Corp., 2001 4 * Copyright (c) 2017 Xiao Yang <yangx.jy@cn.fujitsu.com> 5 */ 6 7/* 8 * DESCRIPTION 9 * 1) Test for EPERM when the super-user tries to increase RLIMIT_NOFILE 10 * beyond the system limit. 11 * 2) Test for EINVAL when rlim->rlim_cur is greater than rlim->rlim_max. 12 */ 13 14#include <errno.h> 15#include <sys/time.h> 16#include <sys/resource.h> 17#include <linux/fs.h> 18#include "tst_test.h" 19 20#if !defined(NR_OPEN) 21// Taken from definition in /usr/include/linux/fs.h 22# define NR_OPEN (1024*1024) 23#endif 24 25#define NR_OPEN_PATH "/proc/sys/fs/nr_open" 26 27static struct rlimit rlim1, rlim2; 28static unsigned int nr_open = NR_OPEN; 29 30static struct tcase { 31 struct rlimit *rlimt; 32 int exp_err; 33} tcases[] = { 34 {&rlim1, EPERM}, 35 {&rlim2, EINVAL} 36}; 37 38static void verify_setrlimit(unsigned int n) 39{ 40 struct tcase *tc = &tcases[n]; 41 42 TEST(setrlimit(RLIMIT_NOFILE, tc->rlimt)); 43 if (TST_RET != -1) { 44 tst_res(TFAIL, "call succeeded unexpectedly " 45 "(nr_open=%u rlim_cur=%lu rlim_max=%lu)", nr_open, 46 (unsigned long)(tc->rlimt->rlim_cur), 47 (unsigned long)(tc->rlimt->rlim_max)); 48 return; 49 } 50 51 if (TST_ERR != tc->exp_err) { 52 tst_res(TFAIL | TTERRNO, "setrlimit() should fail with %s, got", 53 tst_strerrno(tc->exp_err)); 54 } else { 55 tst_res(TPASS | TTERRNO, "setrlimit() failed as expected"); 56 } 57} 58 59static void setup(void) 60{ 61 if (!access(NR_OPEN_PATH, F_OK)) 62 SAFE_FILE_SCANF(NR_OPEN_PATH, "%u", &nr_open); 63 64 SAFE_GETRLIMIT(RLIMIT_NOFILE, &rlim1); 65 rlim2.rlim_max = rlim1.rlim_cur; 66 rlim2.rlim_cur = rlim1.rlim_max + 1; 67 rlim1.rlim_max = nr_open + 1; 68} 69 70static struct tst_test test = { 71 .setup = setup, 72 .tcnt = ARRAY_SIZE(tcases), 73 .test = verify_setrlimit, 74 .needs_root = 1 75}; 76