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 mlock() 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)34int 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 = mlock(page_ptr, BUFSIZE); 48 49 if (result == -1 && errno == ENOMEM) { 50 printf("Test PASSED\n"); 51 return PTS_PASS; 52 } else if (errno == EPERM) { 53 printf 54 ("You don't have permission to lock your address space.\nTry to rerun this test as root.\n"); 55 return PTS_UNRESOLVED; 56 } else { 57 perror("Unexpected error"); 58 return PTS_UNRESOLVED; 59 } 60 61 } 62