Created
July 22, 2021 08:35
-
-
Save shqking/01c4a6a5567323e36e4bea22fca3ea16 to your computer and use it in GitHub Desktop.
mmap-twice
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/mman.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <limits.h> | |
#include <fcntl.h> | |
#include <sys/stat.h> | |
#define READ_ADDR(addr, offset) printf("==" #addr ": offset " #offset ": %p, value: %d\n", addr + offset, *(addr + offset)); | |
int main() | |
{ | |
// 'tempplate' should be a char array. https://man7.org/linux/man-pages/man3/mkstemp.3.html | |
static char fname[] = "/tmp/tmpphp-XXXXXX"; | |
char template[PATH_MAX]; | |
strcpy(template, fname); | |
// Create one temp file | |
int fd = mkstemp(template); | |
printf("Filename is %s\n", template); | |
if (fd == -1) | |
{ | |
printf("Error: fail in mkstemp\n"); | |
return 0; | |
} | |
printf("Temp file creation succeeds with fd %d\n", fd); | |
// File size | |
int size = 0xa000000; // big size | |
write(fd, 0, size); | |
struct stat sb; | |
if (fstat(fd, &sb) == -1) | |
{ | |
printf("Error: fail in fstat\n"); | |
return 0; | |
} | |
printf("Temp file size: 0x%llx\n", sb.st_size); | |
if (size != sb.st_size) | |
{ | |
printf("Error: unexpected file size.\n"); | |
return 0; | |
} | |
printf("\n"); | |
// Map to RW memory | |
char *w_addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | |
if (w_addr == MAP_FAILED) | |
{ | |
printf("Error: fail in mmap\n"); | |
return 0; | |
} | |
printf("w_addr address: start %p, end: %p\n", w_addr, w_addr + size); | |
// Check read access | |
READ_ADDR(w_addr, 0); | |
READ_ADDR(w_addr, 0x10); | |
READ_ADDR(w_addr, 0x100); | |
READ_ADDR(w_addr, 0x1000); | |
READ_ADDR(w_addr, 0x10000); | |
READ_ADDR(w_addr, 0x1000000); | |
READ_ADDR(w_addr, 0xa000000 - 1); | |
// READ_ADDR(w_addr, 0xa000000); // OOB read | |
// Write one value to 0x10000 | |
*(w_addr + 0x10000) = 42; | |
READ_ADDR(w_addr, 0x10000); | |
printf("\n"); | |
// Map to RX memory | |
char *x_addr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); | |
if (x_addr == MAP_FAILED) | |
{ | |
printf("Error: fail in mmap\n"); | |
return 0; | |
} | |
printf("x_addr address: start %p, end: %p\n", x_addr, x_addr + size); | |
// Check read access | |
READ_ADDR(x_addr, 0); | |
READ_ADDR(x_addr, 0x10); | |
READ_ADDR(x_addr, 0x100); | |
READ_ADDR(x_addr, 0x1000); | |
READ_ADDR(x_addr, 0x10000); // Should be 42. Shared with w_addr | |
READ_ADDR(x_addr, 0x1000000); | |
READ_ADDR(x_addr, 0xa000000 - 1); | |
if (*(x_addr + 0x10000) != 42) | |
{ | |
printf("Error: shared?\n"); | |
return 0; | |
} | |
// *(x_addr + 0x10000) = 42; // Not writable... | |
printf("\n"); | |
close(fd); /* Close file */ | |
unlink(template); /* Remove it */ | |
printf("Before fork(): parent pid: %d\n", getpid()); | |
printf("\n"); | |
pid_t pid = fork(); | |
if (pid == -1) | |
{ | |
printf("Error: fail in fork\n"); | |
return 0; | |
} | |
else if (pid == 0) | |
{ | |
// Child process | |
printf("Child process pid: %d\n", getpid()); | |
printf("w_addr address: start %p, end: %p\n", w_addr, w_addr + size); | |
printf("x_addr address: start %p, end: %p\n", x_addr, x_addr + size); | |
// Should be 42. Shared with parent process | |
READ_ADDR(w_addr, 0x10000); | |
READ_ADDR(x_addr, 0x10000); | |
if (*(w_addr + 0x10000) != 42 || *(x_addr + 0x10000) != 42) | |
{ | |
printf("Error: shared with parent?\n"); | |
return 0; | |
} | |
// Write one value to 0x10000 | |
*(w_addr + 0x10000) = 42 * 2; | |
// *(x_addr + 0x10000) = 42 * 3; // Not writable | |
READ_ADDR(w_addr, 0x10000); | |
READ_ADDR(x_addr, 0x10000); | |
printf("\n"); | |
exit(0); | |
} | |
else | |
{ | |
// Parent process | |
sleep(5); | |
printf("Parent process, Forked child is: %d\n", pid); | |
// Should be 84. Shared with parent process | |
READ_ADDR(w_addr, 0x10000); | |
READ_ADDR(x_addr, 0x10000); | |
if (*(w_addr + 0x10000) != 84 || *(x_addr + 0x10000) != 84) | |
{ | |
printf("Error: shared with child?\n"); | |
return 0; | |
} | |
} | |
printf("cool\n"); | |
return 0; | |
} |
Author
shqking
commented
Jul 22, 2021
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment