美文网首页
Linux用户态下判断一个指针的合法性

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

作者: 星夜兼程工作笔记 | 来源:发表于2019-11-18 19:06 被阅读0次

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

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

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

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

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

    #include <stdio.h>

    #include <stdlib.h>

    #include <signal.h>

    #include <setjmp.h>

    #include <unistd.h>

    /*

    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<hi;i++)

            {

                int tmp = *(pi+i);

            }

            for(i=0;i<remain;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用户态下判断一个指针的合法性

          本文链接:https://www.haomeiwen.com/subject/bogbictx.html