The mprotect() system call in C has been used to specify or change the required protection for the process’s memory page(s). This memory page(s) comprises a share or all of the address range in the interval that is: [addr, addr+len-1]. Let’s look at the mprotect() system call to see how it works and is used while using some memory page program in the Ubuntu 20.04 system. So, log in from the Ubuntu 20.04 system and launch your shell console on the desktop by Ctrl+Alt+T.
Let’s have our first example for the mprotect() system call. Create a C-type file in the system within the terminal using a query “touch” as per the stated output image.
Now the file has been properly created, open up it within some editor like GNU or Vim. We have a GNU Editor installed and configured on our Ubuntu 20.04 system. So, we have been using it to open the newly made C file as per the instruction shown in the image.
Now added up some required C libraries for the working of a mprotect() system call. We have defined a built-in handle-error method used to display the message passed in its argument upon some issue. A method “handler” has been defined here, and it generates the signal SIGSEGV when a handler method tries to get memory in a way that intrudes upon the protection. It also fetches the page address where this error has been found.
The main function has been defined here to start the execution of C code. A character type pointer has been defined, and an integer “psize” has been defined to set page size. The structure sigaction “s” has been defined here to handle a signal. The sigaction flag has been used to get specify the signal handling method using SA_SIGINFO. Within the execution, the system has blocked the additional set of signals using sa_mask and make the queue empty by sigemptyset. The sa_sigaction stores the address of the signal handler for the signals that are not queued.
If the sigaction function pass signal as “SIGSEGV”, pointer and NULL method and the function returns -1, the handle error will get “sigaction” as the error, and the page size has been saved to psize. If the size is less than 0, the sysconf error will be sent. The memory of 4 pages has been assigned to buffer. If the buffer is null, the error “memalign” will be sent. The print statement will display the initial address of a buffer. Another if statement has been used here to check memory protection and increment the index of the buffer.
Upon the compilation by gcc command and execution, we have got that it displays the original region and then displays the system has got SIGSEGV signal as something goes out of the way.
Let’s have another example to demonstrate the mprotect() system call. Create a new file first.
Open the file.
After the header has been included, an integer and static pointer have been initialized. The handler method has been used here to show that the memory has been accessed. The mprotect system call has been used here to pass memory, size, and some other arguments as parameters.
The main method contains integer type descriptor and structure type sigaction “s”. Then we have installed a handler() method as the SIGSEGV handler. After that, I allocated a 1-page memory to the shown file path and saved it to file descriptor “f”. After mapping the memory, the descriptor has been closed. We will use the variable pointer “m” to get a private copy by writing on a page. Then we have added the mprotect system call to prevent assigning writing rights to memory. Then we have written 1 on the page. This will write on the assigned memory of the page. The print statement has been used to display the completion message, and the munmap() method has been used here to unmap the memory allocated.
Let’s compile and execute this updated code in the terminal using the “gcc” and “./a.out” commands. The system shows that the memory has been accessed, assigned, and unmapped to a single page. The “All Completed!” message has been displayed on your screen.
In this article, we have elaborated on two examples to understand the working of the mprotect() system call to protect the assigned memory to a page. The examples contain the usage of handler functions; memory unmap methods, sigaction structures, and pointers to achieve the desired results.