.\" -*- coding: UTF-8 -*- .\" Copyright (C) 2007 Michael Kerrisk .\" and Copyright (C) 1995 Michael Shields . .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\" Modified 1996-10-22 by Eric S. Raymond .\" Modified 1997-05-31 by Andries Brouwer .\" Modified 2003-08-24 by Andries Brouwer .\" Modified 2004-08-16 by Andi Kleen .\" 2007-06-02, mtk: Fairly substantial rewrites and additions, and .\" a much improved example program. .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH mprotect 2 "3 мая 2023 г." "Linux man\-pages 6.05.01" .SH ИМЯ mprotect, pkey_mprotect \- контролирует доступ к области памяти .SH LIBRARY Standard C library (\fIlibc\fP, \fI\-lc\fP) .SH СИНТАКСИС .nf \fB#include \fP .PP \fBint mprotect(void \fP\fIaddr\fP\fB[.\fP\fIlen\fP\fB], size_t \fP\fIlen\fP\fB, int \fP\fIprot\fP\fB);\fP .PP \fB#define _GNU_SOURCE\fP /* смотрите feature_test_macros(7) */ \fB#include \fP .PP \fBint pkey_mprotect(void \fP\fIaddr\fP\fB[.\fP\fIlen\fP\fB], size_t \fP\fIlen\fP\fB, int \fP\fIprot\fP\fB, int \fP\fIpkey\fP\fB);\fP .fi .SH ОПИСАНИЕ Вызов \fBmprotect\fP() изменяет параметры доступа страниц памяти вызывающего процесса, которые содержатся, даже частично, в адресном диапазоне [\fIaddr\fP,\ \fIaddr\fP+\fIlen\fP\-1]. Значение \fIaddr\fP должно быть выровнено на границу страницы. .PP Если вызывающий процесс нарушает защиту доступа к памяти, то ядро посылает процессу сигнал \fBSIGSEGV\fP. .PP \fIprot\fP is a combination of the following access flags: \fBPROT_NONE\fP or a bitwise OR of the other values in the following list: .TP \fBPROT_NONE\fP Доступ к памяти запрещён. .TP \fBPROT_READ\fP Память можно читать. .TP \fBPROT_WRITE\fP Память можно изменять. .TP \fBPROT_EXEC\fP Память можно выполнять. .TP \fBPROT_SEM\fP (начиная с Linux 2.5.7) Память можно использовать для атомарных операций. Этот флаг появился как часть реализации \fBfutex\fP(2) (для гарантии способности выполнять атомарные операции, требуемые таким командам как \fBFUTEX_WAIT\fP), но пока не используется ни в одной архитектуре. .TP \fBPROT_SAO\fP (начиная с Linux 2.6.26) .\" commit aba46c5027cb59d98052231b36efcbbde9c77a1d .\" commit ef3d3246a0d06be622867d21af25f997aeeb105f Память должна иметь строгий порядок доступа. Это свойство есть только в архитектуре PowerPC (в спецификации архитектуры версии 2.06 добавлено свойство ЦП SAO и оно доступно, например, на POWER 7 или PowerPC A2). .PP Также (начиная с Linux 2.6.0), \fIprot\fP может содержать один из следующих установленных флагов: .TP .\" mm/mmap.c: .\" vm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) | .\" mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; .\" And calc_vm_flag_bits converts only GROWSDOWN/DENYWRITE/LOCKED. \fBPROT_GROWSUP\fP .\" The VMA is one that was marked with VM_GROWSUP by the kernel .\" when the stack was created. Note that (unlike VM_GROWSDOWN), .\" there is no mmap() flag (analogous to MAP_GROWSDOWN) for .\" creating a VMA that is marked VM_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\[em]for example, HP\-PARISC\[em]that have an upwardly growing stack.) .TP \fBPROT_GROWSDOWN\fP Применить режим защиты до начала отображения, которое растёт вниз (которое должно быть сегментом стека или сегментом, отображённым с установленным флагом \fBMAP_GROWSDOWN\fP). .PP Подобно \fBmprotect\fP(), вызов \fBpkey_mprotect\fP() изменяет защиту страниц, указанных \fIaddr\fP и \fIlen\fP. Аргумент \fIpkey\fP содержит ключ защиты (смотрите \fBpkeys\fP(7)), назначаемый памяти. Ключ защиты должен быть выделен с помощью \fBpkey_alloc\fP(2) до передачи в \fBpkey_mprotect\fP(). Пример использования этого системного вызова смотрите в \fBpkeys\fP(7). .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" On success, \fBmprotect\fP() and \fBpkey_mprotect\fP() return zero. On error, these system calls return \-1, and \fIerrno\fP is set to indicate the error. .SH ОШИБКИ .TP \fBEACCES\fP Нельзя задать этот вид доступа. Например, это может случиться, если при вызове \fBmmap\fP(2) файл доступен только на чтение, а запрос \fBmprotect\fP() был \fBPROT_WRITE\fP. .TP \fBEINVAL\fP Значение \fIaddr\fP не является правильным указателем или не кратен размеру системной страницы. .TP \fBEINVAL\fP (\fBpkey_mprotect\fP()) \fIpkey\fP не был выделен с помощью \fBpkey_alloc\fP(2). .TP \fBEINVAL\fP В \fIprot\fP указаны оба флага, \fBPROT_GROWSUP\fP и \fBPROT_GROWSDOWN\fP. .TP \fBEINVAL\fP Указано неверное значение в \fIprot\fP. .TP \fBEINVAL\fP (архитектура PowerPC ) В \fIprot\fP указан \fBPROT_SAO\fP, но недоступно аппаратное свойство SAO. .TP \fBENOMEM\fP Не удалось выделить место под внутренние структуры ядра. .TP \fBENOMEM\fP Addresses in the range [\fIaddr\fP, \fIaddr\fP+\fIlen\fP\-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 \fBEFAULT\fP was incorrectly produced for these cases.) .TP \fBENOMEM\fP .\" I.e., the number of VMAs would exceed the 64 kB maximum Изменение защиты области памяти привело бы к превышению разрешённого максимума на количество отображений с различающимися атрибутами (защита на чтение и на чтение/запись). Например, защита диапазона \fBPROT_READ\fP в середине области, которая сейчас защищена \fBPROT_READ|PROT_WRITE\fP, привела бы к трём отображениям: два отображения на концах, доступных на чтение/запись и доступное только для чтение отображение посередине. .SH ВЕРСИИ .\" SVr4 defines an additional error .\" code EAGAIN. The SVr4 error conditions don't map neatly onto Linux's. POSIX says that the behavior of \fBmprotect\fP() is unspecified if it is applied to a region of memory that was not obtained via \fBmmap\fP(2). .PP В Linux всегда можно вызвать \fBmprotect\fP() с любым адресом из адресного пространства процесса (за исключением области ядра vsyscall). В частности, это можно использовать для изменения отображений существующего кода на записываемые. .PP Отличается ли действие \fBPROT_EXEC\fP от \fBPROT_READ\fP зависит от архитектуры процессора, версии ядра и состояния процесса. Если в флагах специализаций процессора установлен \fBREAD_IMPLIES_EXEC\fP (смотрите \fBpersonality\fP(2)), то указание \fBPROT_READ\fP подразумевает добавление \fBPROT_EXEC\fP. .PP На некоторых аппаратных архитектурах (например, i386) \fBPROT_WRITE\fP подразумевает \fBPROT_READ\fP. .PP В POSIX.1 сказано, что реализация может разрешить доступ отличный от указанного в \fIprot\fP, но для доступа на запись должен быть обязательно установлен флаг \fBPROT_WRITE\fP, и любой доступ должен быть запрещён, если установлен флаг \fBPROT_NONE\fP. .PP В приложениях нужно осторожно использовать \fBmprotect\fP() и \fBpkey_mprotect\fP() вместе. На x86, если \fBmprotect\fP() используется с установленным в \fIprot\fP значением \fBPROT_EXEC\fP, то pkey может быть выделен и установлен ядром в память неявным образом, но только если до этого pkey был равен 0. .PP В системах без аппаратной поддержки ключей защиты \fBpkey_mprotect\fP() всё ещё можно использовать, но значение \fIpkey\fP должно быть равно \-1. При таком вызове операция \fBpkey_mprotect\fP() эквивалентна \fBmprotect\fP(). .SH СТАНДАРТЫ .TP \fBmprotect\fP() POSIX.1\-2008. .TP \fBpkey_mprotect\fP() Linux. .SH ИСТОРИЯ .TP \fBmprotect\fP() POSIX.1\-2001, SVr4. .TP \fBpkey_mprotect\fP() Linux 4.9, glibc 2.27. .SH ЗАМЕЧАНИЯ .SH ПРИМЕРЫ .\" sigaction.2 refers to this example Программа, представленная далее, показывает использование \fBmprotect\fP(). Она выделяет четыре страницы памяти, делает третью доступной только на чтение, а затем запускает цикл, который проходит по выделенной области, меняя байты. .PP Результат работы программы: .PP .in +4n .EX $\fB ./a.out\fP Начало области: 0x804c000 Получен SIGSEGV при адресе: 0x804e000 .EE .in .SS "Исходный код программы" .\" SRC BEGIN (mprotect.c) \& .EX #include #include #include #include #include #include \& #define handle_error(msg) \e 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\en", 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\en", buffer); \& if (mprotect(buffer + pagesize * 2, pagesize, PROT_READ) == \-1) handle_error("mprotect"); \& for (char *p = buffer ; ; ) *(p++) = \[aq]a\[aq]; \& printf("Loop completed\en"); /* Should never happen */ exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "СМ. ТАКЖЕ" \fBmmap\fP(2), \fBsysconf\fP(3), \fBpkeys\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства был сделан aereiae , Alexey , Azamat Hackimov , Dmitriy S. Seregin , Dmitry Bolkhovskikh , ITriskTI , Max Is , Yuri Kozlov , Иван Павлов и Малянов Евгений Викторович . .PP Этот перевод является бесплатной документацией; прочитайте .UR https://www.gnu.org/licenses/gpl-3.0.html Стандартную общественную лицензию GNU версии 3 .UE или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. .PP Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на .MT man-pages-ru-talks@lists.sourceforge.net .ME .