mmap
- Tags
- comp-arch
Is a system-call that allows you map pages into memory and share them with child processes. The memory for this could come from a file stored on a disk or from a shared or typed memory object. See mmap and munmap.
// Open the file to mmap.
int fd = open(argv[1], O_RDWR);
// Stat it to get its file size.
size_t length;
struct stat sb;
fstat(fd, &sb);
// Must be a multiple of the page size for the system.
off_t offset;
off_t page_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
// mmap into our processes memory.
char *addr = mmap(NULL, length + offset - page_offset, PROT_READ|PROT_WRITE,
MAP_PRIVATE, fd, page_offset);
// Write the body of the file to stdout.
write(1, addr + offset - page_offset, length);
// Unmmap and close the file descriptor.
munmap(addr, length + offset - pa_offset);
close(fd);
Symbolic Constant | Description |
---|---|
PROT_READ | Data can be read |
PROT_WRITE | Data can be written |
PROT_EXEC | Data can be executed (conflicts with PROT_WRITE ) |
PROT_NONE | Data cannot be accessed (takes precedence over PROT_WRITE ) |
MAP_SHARED | Mapping will be synced with the file object |
MAP_PRIVATE | Mapping won't be visible to the process itself |
Note: PROT_NONE
may seem sort of useless however it's useful for securing a system.
If you prefix and suffix pages containing sensitive information with guard pages then
you decrease the changes of an attack.
Communicating With Sub-processes
Memory mapped through mmap can be accessed through sub-processes directly.
// mmap an array of 100 pointers with no file descriptor.
int size = 100 * sizeof(int);
void *addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
int *shared = addr;
// Fork an modify the value in a subprocess, then print in the parent process.
pid_t mychild = fork();
if (mychild > 0) {
shared[0] = 10;
shared[1] = 20;
} else {
sleep(1); // Check the synchronization chapter for a better way
printf("%d\n", shared[1] + shared[0]);
}
// Cleanup
munmap(addr, size);