Skip to content

Instantly share code, notes, and snippets.

@FauxFaux
Created April 12, 2017 23:43
Show Gist options
  • Save FauxFaux/9032a665250fbcbe6fe6060ebe93a14f to your computer and use it in GitHub Desktop.
Save FauxFaux/9032a665250fbcbe6fe6060ebe93a14f to your computer and use it in GitHub Desktop.
Repairing a SIGBUS from an OOB read of an mmap'd file
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
char *ptr;
int fd;
const size_t range = 1024*1024*1024;
volatile sig_atomic_t resized = 0;
static void handler(int sig, siginfo_t *si, void *unused) {
char *read_addr = si->si_addr;
ptrdiff_t diff = read_addr - ptr;
// if it's within the bounds of our mapped range..
if (diff >= 0 && diff <= range) {
// if the file is already big enough, panic!
off_t size = lseek(fd, 0, SEEK_END);
if (diff <= size || -1 == size) {
exit(67);
}
// enlarge the file so the read can succeed
if (ftruncate(fd, diff)) {
exit(68);
}
// report error
resized = 1 + size;
} else {
exit(69);
}
}
int main() {
fd = open("data", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
perror("open");
return 3;
}
ptr = mmap(NULL, range, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (-1 == ptr) {
perror("mmap");
return 3;
}
struct sigaction sa = {};
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = &handler;
assert(-1 != sigaction(SIGBUS, &sa, NULL));
char found = ptr[9005];
if (resized) {
printf("first reading failed, fixing file back to original observed length: %d\n", resized - 1);
if (ftruncate(fd, resized - 1)) {
perror("couldn't retruncate");
}
return 5;
} else {
printf("first read success: %d\n", (int)found);
}
char found2 = ptr[90005];
if (resized) {
printf("second reading failed, fixing file back to original observed length: %d\n", resized - 1);
if (ftruncate(fd, resized - 1)) {
perror("couldn't retruncate");
}
return 6;
} else {
printf("second read success: %d\n", (int)found2);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment