mprotect(2) System Calls Manual mprotect(2) mprotect, pkey_mprotect - Standard C library (libc, -lc) #include int mprotect(void addr[.size], size_t size, int prot); #define _GNU_SOURCE /* feature_test_macros(7) */ #include int pkey_mprotect(void addr[.size], size_t size, int prot, int pkey); mprotect() changes the access protections for the calling process's memory pages containing any part of the address range in the interval [addr, addr+size-1]. addr must be aligned to a page boundary. , SIGSEGV. prot is a combination of the following access flags: PROT_NONE or a bitwise OR of the other values in the following list: PROT_NONE . PROT_READ . PROT_WRITE . PROT_EXEC . PROT_SEM ( Linux 2.5.7) . futex(2) ( , FUTEX_WAIT), . PROT_SAO ( Linux 2.6.26) . PowerPC ( 2.06 SAO , , POWER 7 PowerPC A2). ( Linux 2.6.0), prot : PROT_GROWSUP Apply the protection mode up to the end of a mapping that grows upwards. (Such mappings are created for the stack area on architectures--for example, HP-PARISC--that have an upwardly growing stack.) PROT_GROWSDOWN , ( , MAP_GROWSDOWN). Like mprotect(), pkey_mprotect() changes the protection on the pages specified by addr and size. The pkey argument specifies the protection key (see pkeys(7)) to assign to the memory. The protection key must be allocated with pkey_alloc(2) before it is passed to pkey_mprotect(). For an example of the use of this system call, see pkeys(7). On success, mprotect() and pkey_mprotect() return zero. On error, these system calls return -1, and errno is set to indicate the error. EACCES . , , mmap(2) , mprotect() PROT_WRITE. EINVAL addr . EINVAL (pkey_mprotect()) pkey pkey_alloc(2). EINVAL prot , PROT_GROWSUP PROT_GROWSDOWN. EINVAL prot. EINVAL ( PowerPC ) prot PROT_SAO, SAO. ENOMEM . ENOMEM Addresses in the range [addr, addr+size-1] are invalid for the address space of the process, or specify one or more pages that are not mapped. (Before Linux 2.4.19, the error EFAULT was incorrectly produced for these cases.) ENOMEM ( /). , PROT_READ , PROT_READ|PROT_WRITE, : , / . POSIX says that the behavior of mprotect() is unspecified if it is applied to a region of memory that was not obtained via mmap(2). Linux mprotect() ( vsyscall). , . PROT_EXEC PROT_READ , . READ_IMPLIES_EXEC ( personality(2)), PROT_READ PROT_EXEC. (, i386) PROT_WRITE PROT_READ. POSIX.1 , prot, PROT_WRITE, , PROT_NONE. mprotect() pkey_mprotect() . x86, mprotect() prot PROT_EXEC, pkey , pkey 0. pkey_mprotect() , pkey -1. pkey_mprotect() mprotect(). mprotect() POSIX.1-2008. pkey_mprotect() Linux. mprotect() POSIX.1-2001, SVr4. pkey_mprotect() Linux 4.9, glibc 2.27. , , mprotect(). , , , , . : $ ./a.out : 0x804c000 SIGSEGV : 0x804e000 #include #include #include #include #include #include #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) static char *buffer; static void handler(int sig, siginfo_t *si, void *unused) { /* Note: calling printf() from a signal handler is not safe (and should not be done in production programs), since printf() is not async-signal-safe; see signal-safety(7). Nevertheless, we use printf() here as a simple way of showing that the handler was called. */ printf("Got SIGSEGV at address: %p\n", si->si_addr); exit(EXIT_FAILURE); } int main(void) { int pagesize; struct sigaction sa; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = handler; if (sigaction(SIGSEGV, &sa, NULL) == -1) handle_error("sigaction"); pagesize = sysconf(_SC_PAGE_SIZE); if (pagesize == -1) handle_error("sysconf"); /* Allocate a buffer aligned on a page boundary; initial protection is PROT_READ | PROT_WRITE. */ buffer = memalign(pagesize, 4 * pagesize); if (buffer == NULL) handle_error("memalign"); printf("Start of region: %p\n", buffer); if (mprotect(buffer + pagesize * 2, pagesize, PROT_READ) == -1) handle_error("mprotect"); for (char *p = buffer ; ; ) *(p++) = 'a'; printf("Loop completed\n"); /* Should never happen */ exit(EXIT_SUCCESS); } mmap(2), sysconf(3), pkeys(7) () aereiae , Alexey , Azamat Hackimov , Dmitriy S. Seregin , Dmitry Bolkhovskikh , ITriskTI , Max Is , Yuri Kozlov , , Kirill Rekhov ; GNU (GNU General Public License - GPL, 3 ) , - . - , , () () () <>. Linux man-pages 6.12 17 2024 . mprotect(2)