diff --git a/scan_asn1rawint.c b/scan_asn1rawint.c index e331805..607f08c 100644 --- a/scan_asn1rawint.c +++ b/scan_asn1rawint.c @@ -39,6 +39,33 @@ size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* l) { #include #include +#ifdef __linux__ +#include +#include +#include + +// 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; diff --git a/scan_asn1tag.c b/scan_asn1tag.c index 988efc0..76ae899 100644 --- a/scan_asn1tag.c +++ b/scan_asn1tag.c @@ -29,14 +29,14 @@ size_t scan_asn1tag(const char* src,const char* max,enum asn1_tagclass* tc,enum #include #include +#ifdef __linux__ #include #include #include -#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 diff --git a/scan_asn1tagint.c b/scan_asn1tagint.c index d7db42c..fee502e 100644 --- a/scan_asn1tagint.c +++ b/scan_asn1tagint.c @@ -24,6 +24,33 @@ size_t scan_asn1tagint(const char* src,const char* bounds,unsigned long* val) { #include +#ifdef __linux__ +#include +#include +#include + +// 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;