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