Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect invalid reads (using code not valgrind)

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.

like image 786
MIA Avatar asked Mar 19 '26 23:03

MIA


1 Answers

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
like image 200
Henrique Bucher Avatar answered Mar 22 '26 14:03

Henrique Bucher



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!