mprotect()--Change Access Protection for Memory Mapping


  Syntax
 #include <sys/types.h>
 #include <sys/mman.h>

 int  mprotect( void *addr,
                 size_t  len,
                 int     protection);    
  Service Program Name: QP0LLIB1

  Default Public Authority: *USE

  Threadsafe: Yes

The mprotect() function is used to change the access protection of a memory mapping to that specified by protection. All whole pages of the process's address space, that were established by the mmap() function, addressed from addr continuing for a length of len will be affected by the change of access protection. You may specify PROT_NONE, PROT_READ, PROT_WRITE, or the inclusive or of PROT_READ and PROT_WRITE as values for the protect parameter.


Parameters

addr
(Input) The starting address of the memory region for which the access is to be changed.

The addr argument must be a multiple of the page size. The sysconf() function may be used to determine the system page size.

len
(Input) The length in bytes of the address range.

protection
(Input) The desired access protection. You may specify PROT_NONE, PROT_READ, PROT_WRITE, or the inclusive or of PROT_READ AND PROT_WRITE as values for the protection argument.

No access through the memory mapping will be permitted if PROT_NONE is specified.

Storage associated with the mapping cannot be altered unless the PROT_WRITE value is specified.

For shared mappings, PROT_WRITE requires that the file descriptor used to establish the map had been opened for write access. A shared mapping is a mapping created with the MAP_SHARED value of the flag parameter of the mmap() function.

Since private mappings do not alter the underlying file, PROT_WRITE may be specified for a mapping that had been created MAP_PRIVATE and had been opened for read access.

The following table shows the symbolic constants allowed for the protection argument.

Symbolic Constant Decimal
Value
Description
PROT_WRITE 2 Write access allowed.
PROT_READ 2 Read access allowed.
PROT_NONE 8 No access allowed.


Authorities

No authorization is required.


Return Value

Upon successful completion, the mprotect() function returns 0. Upon failure, -1 is returned and errno is set to the appropriate error number.


Error Conditions

When the mprotect() function fails, it returns -1 and sets there errno variable as follows.

Error condition Additional information
[EACCES]

If you are accessing a remote file through the Network File System, update operations to file permissions at the server are not reflected at the client until updates to data that is stored locally by the Network File System take place. (Several options on the Add Mounted File System (ADDMFS) command determine the time between refresh operations of local data.) Access to a remote file may also fail due to different mappings of user IDs (UID) or group IDs (GID) on the local and remote systems.

The protection argument specifies a protection that violates the access permission the process has to the underlying mapped file.

If the QSHRMEMCTL system value was 0 at the time the mapping was created, then this continues to limit the allowed access until the mapping is destroyed. An attempt to change the protection of a shared mapping to PROT_WRITE when the QSHRMEMCTL system value had been zero at the time of map creation will result in an errno of EACCES.

[EINVAL]

For example, the addr argument is not a multiple of the page size. This error number also may indicate that the value of the len argument is 0.

[ENOMEM]

The addr argument is out of the allowed range.

[ENOTAVAIL]  
[ENOTSUP]

For mprotect() this can be caused by an invalid combination of access requests on the protection parameter.



Error Messages

The following messages may be sent from this function.

Message ID Error Message Text
CPE3418 E Possible APAR condition or hardware failure.
CPFA0D4 E File system error occurred. Error number &1.
CPF3CF2 E Error(s) occurred during running of &1 API.
CPF9872 E Program or service program &1 in library &2 ended. Reason code &3.


Usage Notes

  1. The address pointer that was returned by mmap() can only be used with the V4R4M0 or later versions of the following languages:
  2. Start of change The application cannot write or store any data via the memory mapping which includes any tagged (16-byte) pointers because the pointer attribute will be lost. Some examples of tagged pointers include space pointers, system pointers, invocation pointers etc..

    If the DTAMDL(*LLP64) parameter is used when compiling an ILE C program, this limitation does not apply as the pointers will be 8 byte pointers, and their pointer attribute will be preserved. End of change


Related Information


Example

See Code disclaimer information for information pertaining to code examples.

The following example creates a file, produces a memory mapping of the file using mmap(), and then changes the protection of the file using mprotect().

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/mman.h>

main(void) {

  size_t bytesWritten =0;
  int fd;
  int PageSize;
  char   textÝ = "This is a test";

 if ( (PageSize = sysconf(_SC_PAGE_SIZE)) < 0) {
    perror("sysconf() Error=");
    return -1;
 }

 fd = open("/tmp/mmprotectTest",
             (O_CREAT | O_TRUNC | O_RDWR),
             (S_IRWXU | S_IRWXG | S_IRWXO) );
  if ( fd < 0 ) {
    perror("open() error");
    return fd;
  }

  off_t lastoffset = lseek( fd, 0, SEEK_SET);
  bytesWritten = write(fd, text, strlen(text));
  if (bytesWritten != strlen(text) ) {
    perror("write error. ");
    return -1;
  }

  lastoffset = lseek( fd, PageSize-1, SEEK_SET);
  bytesWritten = write(fd, " ", 1);   /* grow file to 1 page. */
  if ( bytesWritten != 1 ) {
     perror("write error. ");
     return -1;
  }
      /* mmap the file. */
  void *address;
  int len;
   off_t my_offset = 0;
   len = PageSize;   /* Map one page */
   address =
       mmap(NULL, len, PROT_NONE, MAP_SHARED, fd, my_offset);

   if ( address == MAP_FAILED ) {
       perror("mmap error. " );
       return -1;
     }

     if ( mprotect( address, len, PROT_WRITE) < 0 ) {
          perror("mprotect failed with error:");
          return -1;
      }
      else (void) printf("%s",address);

    close(fd);
    unlink("/tmp/mmprotectTest");
}


API introduced: V5R1
Top | UNIX-Type APIs | APIs by category