Skip to content

Instantly share code, notes, and snippets.

@shqking
Created July 22, 2021 08:35
Show Gist options
  • Save shqking/01c4a6a5567323e36e4bea22fca3ea16 to your computer and use it in GitHub Desktop.
Save shqking/01c4a6a5567323e36e4bea22fca3ea16 to your computer and use it in GitHub Desktop.
mmap-twice
#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;
}
@shqking
Copy link
Author

shqking commented Jul 22, 2021

$ gcc mmap-twice.c -o a; ./a
Filename is /tmp/tmpphp-hVr5Vm
Temp file creation succeeds with fd 3
Temp file size: 0xa000000

w_addr address: start 0x100e7c000, end: 0x10ae7c000
==w_addr: offset 0: 0x100e7c000, value: 0
==w_addr: offset 0x10: 0x100e7c010, value: 0
==w_addr: offset 0x100: 0x100e7c100, value: 0
==w_addr: offset 0x1000: 0x100e7d000, value: 0
==w_addr: offset 0x10000: 0x100e8c000, value: 0
==w_addr: offset 0x1000000: 0x101e7c000, value: 0
==w_addr: offset 0xa000000 - 1: 0x10ae7bfff, value: 0
==w_addr: offset 0x10000: 0x100e8c000, value: 42

x_addr address: start 0x10ae7c000, end: 0x114e7c000
==x_addr: offset 0: 0x10ae7c000, value: 0
==x_addr: offset 0x10: 0x10ae7c010, value: 0
==x_addr: offset 0x100: 0x10ae7c100, value: 0
==x_addr: offset 0x1000: 0x10ae7d000, value: 0
==x_addr: offset 0x10000: 0x10ae8c000, value: 42
==x_addr: offset 0x1000000: 0x10be7c000, value: 0
==x_addr: offset 0xa000000 - 1: 0x114e7bfff, value: 0

Before fork(): parent pid: 13108

Child process pid: 13109
w_addr address: start 0x100e7c000, end: 0x10ae7c000
x_addr address: start 0x10ae7c000, end: 0x114e7c000
==w_addr: offset 0x10000: 0x100e8c000, value: 42
==x_addr: offset 0x10000: 0x10ae8c000, value: 42
==w_addr: offset 0x10000: 0x100e8c000, value: 84
==x_addr: offset 0x10000: 0x10ae8c000, value: 84

Parent process, Forked child is: 13109
==w_addr: offset 0x10000: 0x100e8c000, value: 84
==x_addr: offset 0x10000: 0x10ae8c000, value: 84
cool

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment