Say you allocated a pointer to char like this
char *ptr = malloc(10 * sizeof(char))
If this ptr is passed to another function without passing its size, can we detect that ptr[10] is reading memory that does not belong to this pointer.
I know that if I used valgrind I will get and invalid read, but I want to write a code to throw an exception when this happens.
One possible way to achieve this is using page guards. This is expensive though but will allow you to get an exception when it happens.
#include <cstdint>
#include <cstdio>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <exception>
#include <stdexcept>
void doit( char* p ) {
for ( int j=0; j<20; ++j ) {
fprintf( stderr, "%d %d\n", j, int(p[j]) );
}
}
void trapped(int) {
throw std::runtime_error("Memory violation");
}
int main() {
signal( SIGSEGV, trapped );
int pgsize = getpagesize();
fprintf( stderr, "Page size: %d\n", pgsize );
uint8_t* ptr = (uint8_t*)mmap( NULL, 2*pgsize, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );
if ( ptr == MAP_FAILED ) {
fprintf(stderr, "Memory map failed: %s\n", strerror(errno) );
return 1;
}
int res = mprotect(ptr+pgsize,pgsize,PROT_NONE);
if ( res!=0 ) {
fprintf(stderr, "Failed to protect memory\n");
return 2;
}
char* s = (char*)(ptr + pgsize - 10);
try {
doit( s );
}
catch( std::exception& ex ) {
fprintf( stderr, "Caught exception:%s\n", ex.what());
}
}
Godbolt: https://godbolt.org/z/oaMoTnaPo
The result of the run is:
Page size: 4096
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
Caught exception:Memory violation