Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs - Kernel

This is a discussion on Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs - Kernel ; On Wed, 3 Oct 2007 22:20:46 +0900, KAMEZAWA Hiroyuki wrote: > On Wed, 3 Oct 2007 21:40:29 +0900 > KAMEZAWA Hiroyuki wrote: > > > On Wed, 3 Oct 2007 14:20:07 +0200 (MEST) > > Mikael Pettersson wrote: > > ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs

  1. Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs

    On Wed, 3 Oct 2007 22:20:46 +0900, KAMEZAWA Hiroyuki wrote:
    > On Wed, 3 Oct 2007 21:40:29 +0900
    > KAMEZAWA Hiroyuki wrote:
    >
    > > On Wed, 3 Oct 2007 14:20:07 +0200 (MEST)
    > > Mikael Pettersson wrote:
    > >
    > > > What I don't agree with is the logic itself:
    > > > - You only catch altstack overflow caused by the kernel pushing
    > > > a sigframe. You don't catch overflow caused by the user-space
    > > > signal handler pushing its own stack frame after the sigframe.
    > > > - SUSv3 specifies the effect of altstack overflow as "undefined".
    > > > - The overflow problem can be solved in user-space: allocate the
    > > > altstack with mmap(), then mprotect() the lowest page to prevent
    > > > accesses to it. Any overflow into it, by the kernel's signal
    > > > delivery code or by the user-space signal handler, will be caught.
    > > >
    > > > So this patch gets a NAK from me.
    > > >

    > >
    > > I can understand what you say, but a program which meets this problem
    > > cannot be debugged ;(
    > >
    > > gdb just shows infinit loop of function frames and origignal signal frame
    > > which includes the most important information is overwritten.
    > >

    > there is a difference among user's stack overflow and kernel's.
    > - user's stack overflow just breaks memory next to stack frame.
    > - kernel's altstack overflow, which this patch tries to fix, breaks
    > the bottom of altstack bacause %esp goes back to the bottom
    > of ths altstack when it exceeds altstack range.
    > This behavior overwrite orignail stack frame and shows infinit loop
    > of function call to gdb and never stop with 100% cpu usage.


    The proposed kernel signal delivery patch only handles the case
    where the /sigframe/ ends up overlapping the end of the altstack.
    If the sigframe remains within the altstack boundaries but the
    user-space signal handler adds an /ordinary stack frame/ that
    moves SP beyond the altstack limit, then the kernel patch solves
    nothing and recursive signals will cause altstack wraparound.

    On the other hand, the user-space technique of making the lowest
    page(s) in the altstack inaccessible handles both cases of overflow.

    /Mikael
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs

    On Wed, 3 Oct 2007 15:46:32 +0200 (MEST)
    Mikael Pettersson wrote:
    > The proposed kernel signal delivery patch only handles the case
    > where the /sigframe/ ends up overlapping the end of the altstack.
    > If the sigframe remains within the altstack boundaries but the
    > user-space signal handler adds an /ordinary stack frame/ that
    > moves SP beyond the altstack limit, then the kernel patch solves
    > nothing and recursive signals will cause altstack wraparound.
    >
    > On the other hand, the user-space technique of making the lowest
    > page(s) in the altstack inaccessible handles both cases of overflow.
    >

    Hmm, okay. Then, this fix is not enough. I see.
    I'll consider how to eduacate users.

    Thanks,
    -Kame
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs

    KAMEZAWA Hiroyuki wrote::
    > On Wed, 3 Oct 2007 15:46:32 +0200 (MEST)
    > Mikael Pettersson wrote:
    >> The proposed kernel signal delivery patch only handles the case
    >> where the /sigframe/ ends up overlapping the end of the altstack.
    >> If the sigframe remains within the altstack boundaries but the
    >> user-space signal handler adds an /ordinary stack frame/ that
    >> moves SP beyond the altstack limit, then the kernel patch solves
    >> nothing and recursive signals will cause altstack wraparound.
    >>
    >> On the other hand, the user-space technique of making the lowest
    >> page(s) in the altstack inaccessible handles both cases of overflow.
    >>

    > Hmm, okay. Then, this fix is not enough. I see.
    > I'll consider how to eduacate users.


    Excuse me. What will Mr.Kamezawa educate users? How to use sigaltstack?

    Following is about using mmap/mprotect. In the previous mail(just now), I have said the same
    thing.Now I say it again in detailed.

    Mikael has told us user'd better to use mmap/mprotect. So I tried to use mmap/mprotect in my test code.

    I want to mprotect() the place from mid to low, and hope it stop the overflow.
    high
    |
    | enable to access
    |
    mid
    |
    | disable to access
    |
    low
    I hope the kernel catch it when the esp beyond the boundaries(mid) in user-space.

    But the altstack wraparound still occurs.
    begin = 0xb7fec000
    end = 0xb7fee000
    esp = 0xb7fedce0
    1
    esp = 0xb7fed9e0
    2
    esp = 0xb7fed6e0
    3
    esp = 0xb7fedce0 <- wraparound
    4
    ....

    Fortunately, when I reuse the patch, wraparound disappeared. Even if I activate the code *1(please
    refer to the following test code).
    So I think we need the patch, in the same time,we advice the user it's better to use mmap/mprotect.

    -----------------------------------------------------------
    #include
    #include
    #include
    #include
    #include
    #include

    #define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
    volatile int counter = 0;

    #ifdef __i386__
    void print_esp()
    {
    unsigned long esp;
    __asm__ __volatile__("movl %%esp, %0":"=g"(esp));

    printf("esp = 0x%08lx\n", esp);
    }
    #endif

    static void segv_handler()
    {
    #ifdef __i386__
    print_esp();
    #endif

    // int i[1000]; //*1

    int *c = NULL;
    counter++;
    printf("%d\n", counter);

    *c = 1; // SEGV
    }

    int main()
    {
    int *c = NULL;
    int pagesize;
    char *addr;
    stack_t stack;
    struct sigaction action;

    pagesize = sysconf(_SC_PAGE_SIZE);
    if (pagesize == -1)
    die("sysconf");

    addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC,
    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (addr == MAP_FAILED)
    die("mmap");

    printf("begin = 0x%08lx\n", addr);
    printf("end = 0x%08lx\n", addr + pagesize * 2);

    if (mprotect(addr, pagesize, PROT_NONE) == -1)
    die("mprotect");

    stack.ss_sp = addr + pagesize;
    stack.ss_flags = 0;
    stack.ss_size = pagesize;
    int error = sigaltstack(&stack, NULL);
    if (error) {
    printf("Failed to use sigaltstack!\n");
    return -1;
    }

    memset(&action, 0, sizeof(action));
    action.sa_handler = segv_handler;
    action.sa_flags = SA_ONSTACK | SA_NODEFER;

    sigemptyset(&action.sa_mask);

    sigaction(SIGSEGV, &action, NULL);

    *c = 0; //SEGV

    return 0;
    }
    -----------------------------------------------------------

    Any suggestion?

    Thanks
    Shi Weihua

    >
    > Thanks,
    > -Kame
    >
    >
    >


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs

    On Thu, 04 Oct 2007 20:56:14 +0900
    Shi Weihua wrote:

    > stack.ss_sp = addr + pagesize;
    > stack.ss_flags = 0;
    > stack.ss_size = pagesize;

    Here is bad.
    stack,ss_sp = addr;
    stack.ss_flags = 0;
    stack.ss_size = pagesize * 2;

    cheers.
    -Kame
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs

    KAMEZAWA Hiroyuki wrote::
    > On Thu, 04 Oct 2007 20:56:14 +0900
    > Shi Weihua wrote:
    >
    >> stack.ss_sp = addr + pagesize;
    >> stack.ss_flags = 0;
    >> stack.ss_size = pagesize;

    > Here is bad.
    > stack,ss_sp = addr;
    > stack.ss_flags = 0;
    > stack.ss_size = pagesize * 2;

    [What the test code want to do]
    addr+pagesize*2 - addr+pagesize -> sigaltstack
    addr+pagesize - addr -> protected region
    The code want to catch overflow when esp enter the protected region.

    But it failed ...
    >
    > cheers.
    > -Kame
    >
    >
    >


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs

    On Thu, 04 Oct 2007 21:33:12 +0900
    Shi Weihua wrote:

    > KAMEZAWA Hiroyuki wrote::
    > > On Thu, 04 Oct 2007 20:56:14 +0900
    > > Shi Weihua wrote:
    > >
    > >> stack.ss_sp = addr + pagesize;
    > >> stack.ss_flags = 0;
    > >> stack.ss_size = pagesize;

    > > Here is bad.
    > > stack,ss_sp = addr;
    > > stack.ss_flags = 0;
    > > stack.ss_size = pagesize * 2;

    > [What the test code want to do]
    > addr+pagesize*2 - addr+pagesize -> sigaltstack
    > addr+pagesize - addr -> protected region
    > The code want to catch overflow when esp enter the protected region.
    >

    You have to protect the top of *registered* sigaltstack.
    The reason of wraparound is %esp will be set to the bottom of sigaltstack
    if it is not on sigaltstack area when signaled.
    What you have to do is protect the top of registerd sigaltstack.
    If %esp is in the range of registerd sigaltstack at SEGV, wraparound
    will stop.

    Thanks,
    -Kame

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread