Linux用户态下判断一个指针的合法性

Windows下面就不多说了:IsBadReadPtr,IsBadStringPtr,IsBadWritePtr。

Linux内核态可以用__access_ok函数来判断内存区域的访问性。

用户态自己写了一个,就是利用了段错误这个信号,然后处理这个信号。用siglongjmp和sigsetjmp在栈里面跳转。

直接Posix族的代码贴出来,应该还有一些小bug,有待继续完善

只把读取权限的写了,别的同理

#include

#include

#include

#include

#include

/*

x86/Linux、x86/Solaris、SPARC/Solaris will sigal SIGSEGV

x86/FreeBSD、x86/NetBSD、x86/OpenBSD MacOS will sigal SIGBUS

*/

#if defined(__MACH__) && defined(__FreeBSD__) && defined(__NetBSD__) && defined(__OpenBSD__)\

    && defined(__DragonFly__)

#define ERROR_SIGNAL SIGBUS

#else

#define ERROR_SIGNAL SIGSEGV

#endif

static sigjmp_buf badreadjmpbuf;

static void badreadfunc(int signo)

{

    /*write(STDOUT_FILENO, "catch\n", 6);*/

    siglongjmp(badreadjmpbuf, 1);

}

int isbadreadptr(void *ptr, int length)

{

    struct sigaction sa, osa;

    int ret = 0;

    /*init new handler struct*/

    sa.sa_handler = badreadfunc;

    sigemptyset(&sa.sa_mask);

    sa.sa_flags = 0;

    /*retrieve old and set new handlers*/

    if(sigaction(ERROR_SIGNAL, &sa, &osa)<0)

        return (-1);

    if(sigsetjmp(badreadjmpbuf, 1) == 0)

    {

        int i, hi=length/sizeof(int), remain=length%sizeof(int);

        int* pi = ptr;

        char* pc = (char*)ptr + hi;

        for(i=0;i

        {

            int tmp = *(pi+i);

        }

        for(i=0;i

        {

            char tmp = *(pc+i);

        }

    }

    else

    {

        ret = 1;

    }

    /*restore prevouis signal actions*/

    if(sigaction(ERROR_SIGNAL, &osa, NULL)<0)

        return (-1);

    return ret;

}

int main()

{

    int *p = 0;

    int flag;

    int testint = 1234567890, *teststack = &testint;

    int * testheap = malloc(sizeof(int) * 10);

    printf("bad ptr %d\n", isbadreadptr(p, 4));

    printf("bad ptr %d\n", isbadreadptr(teststack, 4));

    printf("bad ptr %d\n", isbadreadptr(testheap, 40));

    free(testheap);

    printf("exiting main\n");

    return 0;

}

你可能感兴趣的:(Linux用户态下判断一个指针的合法性)