1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (C) Bull S.A. 2005. $ 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify it 5f08c3bdfSopenharmony_ci * under the terms of version 2 of the GNU General Public License as 6f08c3bdfSopenharmony_ci * published by the Free Software Foundation. 7f08c3bdfSopenharmony_ci * 8f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, but 9f08c3bdfSopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 10f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License along 13f08c3bdfSopenharmony_ci * with this program; if not, write the Free Software Foundation, Inc., 14f08c3bdfSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 15f08c3bdfSopenharmony_ci * 16f08c3bdfSopenharmony_ci */ 17f08c3bdfSopenharmony_ci/************************************************************************** 18f08c3bdfSopenharmony_ci * 19f08c3bdfSopenharmony_ci * TEST IDENTIFIER : mlockall03 20f08c3bdfSopenharmony_ci * 21f08c3bdfSopenharmony_ci * EXECUTED BY : root / superuser 22f08c3bdfSopenharmony_ci * 23f08c3bdfSopenharmony_ci * TEST TITLE : Test for checking basic error conditions for 24f08c3bdfSopenharmony_ci * mlockall(2) 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * TEST CASE TOTAL : 3 27f08c3bdfSopenharmony_ci * 28f08c3bdfSopenharmony_ci * AUTHOR : Jacky Malcles 29f08c3bdfSopenharmony_ci * 30f08c3bdfSopenharmony_ci * SIGNALS 31f08c3bdfSopenharmony_ci * Uses SIGUSR1 to pause before test if option set. 32f08c3bdfSopenharmony_ci * (See the parse_opts(3) man page). 33f08c3bdfSopenharmony_ci * 34f08c3bdfSopenharmony_ci * DESCRIPTION 35f08c3bdfSopenharmony_ci *$ 36f08c3bdfSopenharmony_ci * Verify that mlockall(2) returns -1 and sets errno to 37f08c3bdfSopenharmony_ci * 38f08c3bdfSopenharmony_ci * 1) ENOMEM - If the caller had a non-zero RLIMIT_MEMLOCK 39f08c3bdfSopenharmony_ci * and tried to lock more memory than the limit permitted. 40f08c3bdfSopenharmony_ci * 2) EPERM - If the caller was not privileged 41f08c3bdfSopenharmony_ci * and its RLIMIT_MEMLOCK soft resource limit was 0. 42f08c3bdfSopenharmony_ci * 3) EINVAL - Unknown flags were specified. 43f08c3bdfSopenharmony_ci * 44f08c3bdfSopenharmony_ci * Setup: 45f08c3bdfSopenharmony_ci * Setup signal handling. 46f08c3bdfSopenharmony_ci * Pause for SIGUSR1 if option specified. 47f08c3bdfSopenharmony_ci * 48f08c3bdfSopenharmony_ci * Test: 49f08c3bdfSopenharmony_ci * Loop if the proper options are given. 50f08c3bdfSopenharmony_ci * Do necessary setup for each test. 51f08c3bdfSopenharmony_ci * Execute system call 52f08c3bdfSopenharmony_ci * Check return code, if system call failed and errno == expected errno 53f08c3bdfSopenharmony_ci * Issue sys call passed with expected return value and errno. 54f08c3bdfSopenharmony_ci * Otherwise, 55f08c3bdfSopenharmony_ci * Issue sys call failed to produce expected error. 56f08c3bdfSopenharmony_ci * Do cleanup for each test. 57f08c3bdfSopenharmony_ci * 58f08c3bdfSopenharmony_ci * Cleanup: 59f08c3bdfSopenharmony_ci * Print errno log and/or timing stats if options given 60f08c3bdfSopenharmony_ci * 61f08c3bdfSopenharmony_ci * USAGE: <for command-line> 62f08c3bdfSopenharmony_ci * mlockall03 [-c n] [-e] [-i n] [-I x] [-p x] [-t] 63f08c3bdfSopenharmony_ci * where, 64f08c3bdfSopenharmony_ci * -c n : Run n copies concurrently 65f08c3bdfSopenharmony_ci * -e : Turn on errno logging. 66f08c3bdfSopenharmony_ci * -h : Show this help screen 67f08c3bdfSopenharmony_ci * -i n : Execute test n times. 68f08c3bdfSopenharmony_ci * -I x : Execute test for x seconds. 69f08c3bdfSopenharmony_ci * -p : Pause for SIGUSR1 before starting 70f08c3bdfSopenharmony_ci * -P x : Pause for x seconds between iterations. 71f08c3bdfSopenharmony_ci * -t : Turn on syscall timing. 72f08c3bdfSopenharmony_ci * 73f08c3bdfSopenharmony_ci * RESTRICTIONS 74f08c3bdfSopenharmony_ci * Test must run as root. 75f08c3bdfSopenharmony_ci *****************************************************************************/ 76f08c3bdfSopenharmony_ci#include <errno.h> 77f08c3bdfSopenharmony_ci#include <unistd.h> 78f08c3bdfSopenharmony_ci#include <pwd.h> 79f08c3bdfSopenharmony_ci#include <ctype.h> 80f08c3bdfSopenharmony_ci#include <sys/mman.h> 81f08c3bdfSopenharmony_ci#include "test.h" 82f08c3bdfSopenharmony_ci#include "safe_macros.h" 83f08c3bdfSopenharmony_ci#include <sys/resource.h> 84f08c3bdfSopenharmony_ci#include <sys/utsname.h> 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_civoid setup(); 87f08c3bdfSopenharmony_ciint setup_test(int); 88f08c3bdfSopenharmony_ciint compare(char s1[], char s2[]); 89f08c3bdfSopenharmony_civoid cleanup_test(int); 90f08c3bdfSopenharmony_civoid cleanup(); 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_cichar *TCID = "mlockall03"; 93f08c3bdfSopenharmony_ciint TST_TOTAL = 3; 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci#if !defined(UCLINUX) 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_cichar *ref_release = "2.6.8\0"; 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_cistruct test_case_t { 100f08c3bdfSopenharmony_ci int flag; /* flag value */ 101f08c3bdfSopenharmony_ci int error; /* error description */ 102f08c3bdfSopenharmony_ci char *edesc; /* Expected error no */ 103f08c3bdfSopenharmony_ci} TC[] = { 104f08c3bdfSopenharmony_ci { 105f08c3bdfSopenharmony_ci MCL_CURRENT, ENOMEM, 106f08c3bdfSopenharmony_ci "tried to lock more memory than the limit permitted"}, { 107f08c3bdfSopenharmony_ci MCL_CURRENT, EPERM, "Not a superuser and RLIMIT_MEMLOCK was 0"}, { 108f08c3bdfSopenharmony_ci ~(MCL_CURRENT | MCL_FUTURE), EINVAL, "Unknown flag"} 109f08c3bdfSopenharmony_ci}; 110f08c3bdfSopenharmony_ci 111f08c3bdfSopenharmony_ciint main(int ac, char **av) 112f08c3bdfSopenharmony_ci{ 113f08c3bdfSopenharmony_ci int lc, i; 114f08c3bdfSopenharmony_ci struct utsname *buf; 115f08c3bdfSopenharmony_ci 116f08c3bdfSopenharmony_ci tst_parse_opts(ac, av, NULL, NULL); 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci /* allocate some space for buf */ 119f08c3bdfSopenharmony_ci if ((buf = malloc((size_t)sizeof(struct utsname))) == NULL) { 120f08c3bdfSopenharmony_ci tst_brkm(TFAIL, NULL, "malloc failed for buf"); 121f08c3bdfSopenharmony_ci } 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ci if (uname(buf) < 0) { 124f08c3bdfSopenharmony_ci tst_resm(TFAIL, "uname failed getting release number"); 125f08c3bdfSopenharmony_ci } 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci if ((compare(ref_release, buf->release)) <= 0) { 128f08c3bdfSopenharmony_ci tst_brkm(TCONF, 129f08c3bdfSopenharmony_ci NULL, 130f08c3bdfSopenharmony_ci "In Linux 2.6.8 and earlier this test will not run."); 131f08c3bdfSopenharmony_ci } 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci setup(); 134f08c3bdfSopenharmony_ci 135f08c3bdfSopenharmony_ci /* check looping state */ 136f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); lc++) { 137f08c3bdfSopenharmony_ci 138f08c3bdfSopenharmony_ci tst_count = 0; 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_ci for (i = 0; i < TST_TOTAL; i++) { 141f08c3bdfSopenharmony_ci 142f08c3bdfSopenharmony_ci if (setup_test(i)) { 143f08c3bdfSopenharmony_ci tst_resm(TFAIL, "mlockall() Failed while setup " 144f08c3bdfSopenharmony_ci "for checking error %s", TC[i].edesc); 145f08c3bdfSopenharmony_ci continue; 146f08c3bdfSopenharmony_ci } 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_ci TEST(mlockall(TC[i].flag)); 149f08c3bdfSopenharmony_ci 150f08c3bdfSopenharmony_ci /* check return code */ 151f08c3bdfSopenharmony_ci if (TEST_RETURN == -1) { 152f08c3bdfSopenharmony_ci if (TEST_ERRNO != TC[i].error) 153f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, 154f08c3bdfSopenharmony_ci "mlockall() Failed with wrong " 155f08c3bdfSopenharmony_ci "errno, expected errno=%s, " 156f08c3bdfSopenharmony_ci "got errno=%d : %s", 157f08c3bdfSopenharmony_ci TC[i].edesc, TEST_ERRNO, 158f08c3bdfSopenharmony_ci strerror(TEST_ERRNO)); 159f08c3bdfSopenharmony_ci else 160f08c3bdfSopenharmony_ci tst_resm(TPASS, 161f08c3bdfSopenharmony_ci "expected failure - errno " 162f08c3bdfSopenharmony_ci "= %d : %s", 163f08c3bdfSopenharmony_ci TEST_ERRNO, 164f08c3bdfSopenharmony_ci strerror(TEST_ERRNO)); 165f08c3bdfSopenharmony_ci } else { 166f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, 167f08c3bdfSopenharmony_ci "mlockall() Failed, expected " 168f08c3bdfSopenharmony_ci "return value=-1, got %ld", 169f08c3bdfSopenharmony_ci TEST_RETURN); 170f08c3bdfSopenharmony_ci } 171f08c3bdfSopenharmony_ci cleanup_test(i); 172f08c3bdfSopenharmony_ci } 173f08c3bdfSopenharmony_ci } 174f08c3bdfSopenharmony_ci 175f08c3bdfSopenharmony_ci /* cleanup and exit */ 176f08c3bdfSopenharmony_ci cleanup(); 177f08c3bdfSopenharmony_ci 178f08c3bdfSopenharmony_ci tst_exit(); 179f08c3bdfSopenharmony_ci} 180f08c3bdfSopenharmony_ci 181f08c3bdfSopenharmony_ci/* 182f08c3bdfSopenharmony_ci * setup() - performs all ONE TIME setup for this test. 183f08c3bdfSopenharmony_ci */ 184f08c3bdfSopenharmony_civoid setup(void) 185f08c3bdfSopenharmony_ci{ 186f08c3bdfSopenharmony_ci 187f08c3bdfSopenharmony_ci tst_require_root(); 188f08c3bdfSopenharmony_ci 189f08c3bdfSopenharmony_ci tst_sig(FORK, DEF_HANDLER, cleanup); 190f08c3bdfSopenharmony_ci 191f08c3bdfSopenharmony_ci TEST_PAUSE; 192f08c3bdfSopenharmony_ci 193f08c3bdfSopenharmony_ci return; 194f08c3bdfSopenharmony_ci} 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_ciint compare(char s1[], char s2[]) 197f08c3bdfSopenharmony_ci{ 198f08c3bdfSopenharmony_ci int i = 0; 199f08c3bdfSopenharmony_ci while (s1[i] == s2[i] && s1[i]) 200f08c3bdfSopenharmony_ci i++; 201f08c3bdfSopenharmony_ci 202f08c3bdfSopenharmony_ci if (i < 4) 203f08c3bdfSopenharmony_ci return s2[i] - s1[i]; 204f08c3bdfSopenharmony_ci if ((i == 4) && (isalnum(s2[i + 1]))) { 205f08c3bdfSopenharmony_ci return 1; 206f08c3bdfSopenharmony_ci } else { 207f08c3bdfSopenharmony_ci /* it is not an alphanumeric character */ 208f08c3bdfSopenharmony_ci return s2[i] - s1[i]; 209f08c3bdfSopenharmony_ci } 210f08c3bdfSopenharmony_ci return 0; 211f08c3bdfSopenharmony_ci} 212f08c3bdfSopenharmony_ci 213f08c3bdfSopenharmony_ciint setup_test(int i) 214f08c3bdfSopenharmony_ci{ 215f08c3bdfSopenharmony_ci struct rlimit rl; 216f08c3bdfSopenharmony_ci char nobody_uid[] = "nobody"; 217f08c3bdfSopenharmony_ci struct passwd *ltpuser; 218f08c3bdfSopenharmony_ci 219f08c3bdfSopenharmony_ci switch (i) { 220f08c3bdfSopenharmony_ci case 0: 221f08c3bdfSopenharmony_ci ltpuser = getpwnam(nobody_uid); 222f08c3bdfSopenharmony_ci if (seteuid(ltpuser->pw_uid) == -1) { 223f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "seteuid() failed to " 224f08c3bdfSopenharmony_ci "change euid to %d errno = %d : %s", 225f08c3bdfSopenharmony_ci ltpuser->pw_uid, TEST_ERRNO, 226f08c3bdfSopenharmony_ci strerror(TEST_ERRNO)); 227f08c3bdfSopenharmony_ci return 1; 228f08c3bdfSopenharmony_ci } 229f08c3bdfSopenharmony_ci 230f08c3bdfSopenharmony_ci rl.rlim_max = 10; 231f08c3bdfSopenharmony_ci rl.rlim_cur = 7; 232f08c3bdfSopenharmony_ci 233f08c3bdfSopenharmony_ci if (setrlimit(RLIMIT_MEMLOCK, &rl) != 0) { 234f08c3bdfSopenharmony_ci tst_resm(TWARN | TERRNO, "setrlimit failed to set the " 235f08c3bdfSopenharmony_ci "resource for RLIMIT_MEMLOCK to check " 236f08c3bdfSopenharmony_ci "for mlockall() error %s\n", TC[i].edesc); 237f08c3bdfSopenharmony_ci return 1; 238f08c3bdfSopenharmony_ci } 239f08c3bdfSopenharmony_ci return 0; 240f08c3bdfSopenharmony_ci case 1: 241f08c3bdfSopenharmony_ci rl.rlim_max = 0; 242f08c3bdfSopenharmony_ci rl.rlim_cur = 0; 243f08c3bdfSopenharmony_ci 244f08c3bdfSopenharmony_ci if (setrlimit(RLIMIT_MEMLOCK, &rl) != 0) { 245f08c3bdfSopenharmony_ci tst_resm(TWARN, "setrlimit failed to set the " 246f08c3bdfSopenharmony_ci "resource for RLIMIT_MEMLOCK to check " 247f08c3bdfSopenharmony_ci "for mlockall() error %s\n", TC[i].edesc); 248f08c3bdfSopenharmony_ci return 1; 249f08c3bdfSopenharmony_ci } 250f08c3bdfSopenharmony_ci 251f08c3bdfSopenharmony_ci ltpuser = getpwnam(nobody_uid); 252f08c3bdfSopenharmony_ci if (seteuid(ltpuser->pw_uid) == -1) { 253f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "seteuid() failed to " 254f08c3bdfSopenharmony_ci "change euid to %d errno = %d : %s", 255f08c3bdfSopenharmony_ci ltpuser->pw_uid, TEST_ERRNO, 256f08c3bdfSopenharmony_ci strerror(TEST_ERRNO)); 257f08c3bdfSopenharmony_ci return 1; 258f08c3bdfSopenharmony_ci } 259f08c3bdfSopenharmony_ci 260f08c3bdfSopenharmony_ci return 0; 261f08c3bdfSopenharmony_ci } 262f08c3bdfSopenharmony_ci return 0; 263f08c3bdfSopenharmony_ci} 264f08c3bdfSopenharmony_ci 265f08c3bdfSopenharmony_civoid cleanup_test(int i) 266f08c3bdfSopenharmony_ci{ 267f08c3bdfSopenharmony_ci struct rlimit rl; 268f08c3bdfSopenharmony_ci 269f08c3bdfSopenharmony_ci switch (i) { 270f08c3bdfSopenharmony_ci case 0: 271f08c3bdfSopenharmony_ci case 1: 272f08c3bdfSopenharmony_ci SAFE_SETEUID(cleanup, 0); 273f08c3bdfSopenharmony_ci 274f08c3bdfSopenharmony_ci rl.rlim_max = -1; 275f08c3bdfSopenharmony_ci rl.rlim_cur = -1; 276f08c3bdfSopenharmony_ci 277f08c3bdfSopenharmony_ci if (setrlimit(RLIMIT_MEMLOCK, &rl) != 0) { 278f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, 279f08c3bdfSopenharmony_ci "setrlimit failed to reset the " 280f08c3bdfSopenharmony_ci "resource for RLIMIT_MEMLOCK while " 281f08c3bdfSopenharmony_ci "checking for mlockall() error %s\n", 282f08c3bdfSopenharmony_ci TC[i].edesc); 283f08c3bdfSopenharmony_ci } 284f08c3bdfSopenharmony_ci return; 285f08c3bdfSopenharmony_ci 286f08c3bdfSopenharmony_ci } 287f08c3bdfSopenharmony_ci} 288f08c3bdfSopenharmony_ci 289f08c3bdfSopenharmony_ci#else 290f08c3bdfSopenharmony_ci 291f08c3bdfSopenharmony_ciint main(void) 292f08c3bdfSopenharmony_ci{ 293f08c3bdfSopenharmony_ci tst_resm(TINFO, "test is not available on uClinux"); 294f08c3bdfSopenharmony_ci tst_exit(); 295f08c3bdfSopenharmony_ci} 296f08c3bdfSopenharmony_ci 297f08c3bdfSopenharmony_ci#endif /* if !defined(UCLINUX) */ 298f08c3bdfSopenharmony_ci 299f08c3bdfSopenharmony_ci/* 300f08c3bdfSopenharmony_ci * cleanup() - performs all ONE TIME cleanup for this test at 301f08c3bdfSopenharmony_ci * completion or premature exit. 302f08c3bdfSopenharmony_ci */ 303f08c3bdfSopenharmony_civoid cleanup(void) 304f08c3bdfSopenharmony_ci{ 305f08c3bdfSopenharmony_ci return; 306f08c3bdfSopenharmony_ci} 307