mmap based off-by-one detection

This commit is contained in:
leitner
2022-01-07 22:57:42 +00:00
parent b4def653ac
commit 3d9eb5c7da
3 changed files with 59 additions and 5 deletions

View File

@@ -39,6 +39,33 @@ size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* l) {
#include <assert.h>
#include <string.h>
#ifdef __linux__
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
// This wrapper maps a 64k buffer of memory and makes sure the page
// after it will cause a segfault when accessed. Then we copy the input
// data at the end of the 64k. This is to catch out of bounds reads.
size_t wrapper(const char* src,const char* max,size_t len,long* l) {
static char* base;
if (!base) {
base=mmap(0,64*1024+4*1024,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
assert(base!=MAP_FAILED);
mprotect(base+64*1024,4*1024,PROT_NONE);
}
assert(src<=max && max-src<64*1024);
{
size_t L = max-src;
char* dest=base+64*1024-L;
memcpy(dest, src, L);
return scan_asn1rawint(dest, dest+L, len, l);
}
}
#define scan_asn1rawint wrapper
#endif
int main() {
char buf[10];
long l;

View File

@@ -29,14 +29,14 @@ size_t scan_asn1tag(const char* src,const char* max,enum asn1_tagclass* tc,enum
#include <assert.h>
#include <string.h>
#ifdef __linux__
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#ifdef __linux__
// This wrapper maps a 64k buffer of memory and makes sure the page
// after it will cause a segfault when accessed. This is to catch
// scan_asn1tag when it read out of bounds.
// after it will cause a segfault when accessed. Then we copy the input
// data at the end of the 64k. This is to catch out of bounds reads.
size_t wrapper(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag) {
static char* base;
if (!base) {
@@ -44,13 +44,13 @@ size_t wrapper(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_
assert(base!=MAP_FAILED);
mprotect(base+64*1024,4*1024,PROT_NONE);
}
if (src<=max) {
assert(src<=max && max-src<64*1024);
{
size_t l = max-src;
char* dest=base+64*1024-l;
memcpy(dest, src, l);
return scan_asn1tag(dest, dest+l, tc, tt, tag);
}
return scan_asn1tag(src, max, tc, tt, tag);
}
#define scan_asn1tag wrapper

View File

@@ -24,6 +24,33 @@ size_t scan_asn1tagint(const char* src,const char* bounds,unsigned long* val) {
#include <stdio.h>
#ifdef __linux__
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
// This wrapper maps a 64k buffer of memory and makes sure the page
// after it will cause a segfault when accessed. Then we copy the input
// data at the end of the 64k. This is to catch out of bounds reads.
size_t wrapper(const char* src,const char* max,unsigned long* val) {
static char* base;
if (!base) {
base=mmap(0,64*1024+4*1024,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
assert(base!=MAP_FAILED);
mprotect(base+64*1024,4*1024,PROT_NONE);
}
assert(src<=max && max-src<64*1024);
{
size_t l = max-src;
char* dest=base+64*1024-l;
memcpy(dest, src, l);
return scan_asn1tagint(dest, dest+l, val);
}
}
#define scan_asn1tagint wrapper
#endif
int main() {
char buf[10];
unsigned long l;