1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2.
4 *
5 * This program is distributed in the hope that it will be useful,
6 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 * GNU General Public License for more details.
9 *
10 * Test that the munlock() function sets errno = ENOMEM if some or all of the
11 * address range specified by the addr and len arguments does not correspond to
12 * valid mapped pages in the address space of the process.
13 *
14 * Assume that the value LONG_MAX is an invalid pointer.
15 *
16 * aarch64 linux versions v5.4-rc1 up to v5.6-rc3 may incorrectly report
17 * EINVAL instead of ENOMEM, the fix patch see:
18 * 597399d0cb91 ("arm64: tags: Preserve tags for addresses translated via TTBR1")
19 * d0022c0ef29b ("arm64: memory: Add missing brackets to untagged_addr() macro")
20 *
21 * this bug was introduced because of the following commit, see:
22 * 057d3389108e ("mm: untag user pointers passed to memory syscalls")
23 */
24
25 #include <sys/mman.h>
26 #include <stdio.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <limits.h>
30 #include "posixtest.h"
31
32 #define BUFSIZE 8
33
main(void)34 int main(void)
35 {
36 int result;
37 long page_size;
38 void *page_ptr;
39
40 page_size = sysconf(_SC_PAGESIZE);
41 if (errno) {
42 perror("An error occurs when calling sysconf()");
43 return PTS_UNRESOLVED;
44 }
45
46 page_ptr = (void *)(LONG_MAX - (LONG_MAX % page_size));
47 result = munlock(page_ptr, BUFSIZE);
48
49 if (result == -1 && errno == ENOMEM) {
50 printf("Test PASSED\n");
51 return PTS_PASS;
52 } else {
53 perror("Unexpected error");
54 return PTS_UNRESOLVED;
55 }
56
57 }
58