1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2002 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * 06/2002 Written by Paul Larson 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci/*\ 9f08c3bdfSopenharmony_ci * [Description] 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * Test for ENOMEM, EPERM errors. 12f08c3bdfSopenharmony_ci * 13f08c3bdfSopenharmony_ci * 1) mlock(2) fails with ENOMEM if some of the specified address range 14f08c3bdfSopenharmony_ci * does not correspond to mapped pages in the address space of 15f08c3bdfSopenharmony_ci * the process. 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * 2) mlock(2) fails with ENOMEM if the caller had a non-zero RLIMIT_MEMLOCK 18f08c3bdfSopenharmony_ci * soft resource limit, but tried to lock more memory than the limit 19f08c3bdfSopenharmony_ci * permitted. This limit is not enforced if the process is 20f08c3bdfSopenharmony_ci * privileged (CAP_IPC_LOCK). 21f08c3bdfSopenharmony_ci * 22f08c3bdfSopenharmony_ci * 3) mlock(2) fails with EPERM if the caller was not privileged (CAP_IPC_LOCK) 23f08c3bdfSopenharmony_ci * and its RLIMIT_MEMLOCK soft resource limit was 0. 24f08c3bdfSopenharmony_ci */ 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_ci#include <unistd.h> 27f08c3bdfSopenharmony_ci#include <sys/mman.h> 28f08c3bdfSopenharmony_ci#include <sys/types.h> 29f08c3bdfSopenharmony_ci#include <pwd.h> 30f08c3bdfSopenharmony_ci#include "tst_test.h" 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_cistatic size_t len; 33f08c3bdfSopenharmony_cistatic struct rlimit original; 34f08c3bdfSopenharmony_cistatic struct passwd *ltpuser; 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_cistatic void test_enomem1(void) 37f08c3bdfSopenharmony_ci{ 38f08c3bdfSopenharmony_ci void *addr; 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci addr = SAFE_MMAP(NULL, len, PROT_READ, 41f08c3bdfSopenharmony_ci MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 42f08c3bdfSopenharmony_ci SAFE_MUNMAP(addr, len); 43f08c3bdfSopenharmony_ci TST_EXP_FAIL(mlock(addr, len), ENOMEM, "mlock(%p, %lu)", addr, len); 44f08c3bdfSopenharmony_ci} 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_cistatic void test_enomem2(void) 47f08c3bdfSopenharmony_ci{ 48f08c3bdfSopenharmony_ci void *addr; 49f08c3bdfSopenharmony_ci struct rlimit rl; 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_ci rl.rlim_max = len - 1; 52f08c3bdfSopenharmony_ci rl.rlim_cur = len - 1; 53f08c3bdfSopenharmony_ci SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &rl); 54f08c3bdfSopenharmony_ci addr = SAFE_MMAP(NULL, len, PROT_READ, 55f08c3bdfSopenharmony_ci MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 56f08c3bdfSopenharmony_ci SAFE_SETEUID(ltpuser->pw_uid); 57f08c3bdfSopenharmony_ci TST_EXP_FAIL(mlock(addr, len), ENOMEM, "mlock(%p, %lu)", addr, len); 58f08c3bdfSopenharmony_ci SAFE_SETEUID(0); 59f08c3bdfSopenharmony_ci SAFE_MUNMAP(addr, len); 60f08c3bdfSopenharmony_ci SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &original); 61f08c3bdfSopenharmony_ci} 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic void test_eperm(void) 64f08c3bdfSopenharmony_ci{ 65f08c3bdfSopenharmony_ci void *addr; 66f08c3bdfSopenharmony_ci struct rlimit rl; 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci rl.rlim_max = 0; 69f08c3bdfSopenharmony_ci rl.rlim_cur = 0; 70f08c3bdfSopenharmony_ci SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &rl); 71f08c3bdfSopenharmony_ci addr = SAFE_MMAP(NULL, len, PROT_READ, 72f08c3bdfSopenharmony_ci MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 73f08c3bdfSopenharmony_ci SAFE_SETEUID(ltpuser->pw_uid); 74f08c3bdfSopenharmony_ci TST_EXP_FAIL(mlock(addr, len), EPERM, "mlock(%p, %lu)", addr, len); 75f08c3bdfSopenharmony_ci SAFE_SETEUID(0); 76f08c3bdfSopenharmony_ci SAFE_MUNMAP(addr, len); 77f08c3bdfSopenharmony_ci SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &original); 78f08c3bdfSopenharmony_ci} 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_cistatic void run(void) 81f08c3bdfSopenharmony_ci{ 82f08c3bdfSopenharmony_ci test_enomem1(); 83f08c3bdfSopenharmony_ci test_enomem2(); 84f08c3bdfSopenharmony_ci test_eperm(); 85f08c3bdfSopenharmony_ci} 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_cistatic void setup(void) 88f08c3bdfSopenharmony_ci{ 89f08c3bdfSopenharmony_ci ltpuser = SAFE_GETPWNAM("nobody"); 90f08c3bdfSopenharmony_ci len = getpagesize(); 91f08c3bdfSopenharmony_ci SAFE_GETRLIMIT(RLIMIT_MEMLOCK, &original); 92f08c3bdfSopenharmony_ci} 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_cistatic struct tst_test test = { 95f08c3bdfSopenharmony_ci .needs_root = 1, 96f08c3bdfSopenharmony_ci .setup = setup, 97f08c3bdfSopenharmony_ci .test_all = run, 98f08c3bdfSopenharmony_ci}; 99