From: Shi Weihua <shiwh@cn.fujitsu.com>
To: Mikael Pettersson <mikpe@it.uu.se>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs
Date: Thu, 04 Oct 2007 20:02:36 +0900 [thread overview]
Message-ID: <4704C84C.3080804@cn.fujitsu.com> (raw)
In-Reply-To: <200710031220.l93CK75T028343@harpo.it.uu.se>
Mikael Pettersson wrote::
> On Wed, 03 Oct 2007 17:06:24 +0900, Shi Weihua wrote:
>> Fixing alternative signal stack wraparound.
>>
>> If a process uses alternative signal stack by using sigaltstack()
>> and that stack overflow, stack wraparound occurs.
>> This patch checks whether the signal frame is on the alternative
>> stack. If the frame is not on there, kill a signal SIGSEGV to the process forcedly
>> then the process will be terminated.
>>
>> This patch is for i386,version is 2.6.23-rc8.
>>
>> Signed-off-by: Shi Weihua <shiwh@cn.fujitsu.com>
>>
>> diff -pur linux-2.6.23-rc8.orig/arch/i386/kernel/signal.c linux-2.6.23-rc8/arch/i386/kernel/signal.c
>> --- linux-2.6.23-rc8.orig/arch/i386/kernel/signal.c 2007-09-26 09:44:08.000000000 +0900
>> +++ linux-2.6.23-rc8/arch/i386/kernel/signal.c 2007-09-26 13:14:25.000000000 +0900
>> @@ -332,6 +332,10 @@ static int setup_frame(int sig, struct k
>>
>> frame = get_sigframe(ka, regs, sizeof(*frame));
>>
>> + if ((ka->sa.sa_flags & SA_ONSTACK) &&
>> + !sas_ss_flags((unsigned long)frame))
>> + goto give_sigsegv;
>> +
>> if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
>> goto give_sigsegv;
>>
>> @@ -425,6 +429,10 @@ static int setup_rt_frame(int sig, struc
>>
>> frame = get_sigframe(ka, regs, sizeof(*frame));
>>
>> + if ((ka->sa.sa_flags & SA_ONSTACK) &&
>> + !sas_ss_flags((unsigned long)frame))
>> + goto give_sigsegv;
>> +
>> if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
>> goto give_sigsegv;
>
> Your patch description is a little terse. What you do is that
> after the kernel has decided where to put the signal frame,
> you add a check that the base of the frame still lies in the
> altstack range if altstack delivery is requested for the signal,
> and if it doesn't a hard error is forced.
>
> The coding of that logic is fine.
>
> 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.
mmap/mprotect can not avoid this kind of wraparound.
Please compile and run the following test code on i386.
The code want to allow process access from high to mid,and not from mid to low.
high
|
|
mid
|
|
low
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#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 *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");
exit(EXIT_FAILURE);
}
addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
die("mmap");
exit(EXIT_FAILURE);
}
printf("begin = 0x%08lx\n", addr);
printf("end = 0x%08lx\n", addr + pagesize * 2);
if (mprotect(addr, pagesize, PROT_NONE) == -1) {
die("mprotect");
exit(EXIT_FAILURE);
}
stack.ss_sp = addr + pagesize;
stack.ss_flags = 0;
stack.ss_size = pagesize; //SIGSTKSZ;
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
>
> So this patch gets a NAK from me.
>
> /Mikael
>
>
>
next prev parent reply other threads:[~2007-10-04 11:02 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-03 12:20 [PATCH 1/3] signal(i386): alternative signal stack wraparound occurs Mikael Pettersson
2007-10-03 12:40 ` KAMEZAWA Hiroyuki
2007-10-03 13:20 ` KAMEZAWA Hiroyuki
2007-10-04 11:02 ` Shi Weihua [this message]
[not found] <474CF7D5.6010702@cn.fujitsu.com>
2007-11-28 6:07 ` Fw: " Shi Weihua
2007-12-04 13:02 ` Ingo Molnar
2007-12-04 21:52 ` Roland McGrath
2007-12-04 21:57 ` Ingo Molnar
2007-12-05 5:22 ` Shi Weihua
2007-12-05 5:36 ` Roland McGrath
[not found] <20071126143317.dd884128.akpm@linux-foundation.org>
[not found] ` <20071126230242.GA9623@elte.hu>
2007-11-27 3:02 ` Fw: " Roland McGrath
2007-11-27 22:57 ` Arjan van de Ven
-- strict thread matches above, loose matches on Subject: below --
2007-10-04 13:08 Mikael Pettersson
2007-10-05 0:55 ` Shi Weihua
2007-10-03 13:46 Mikael Pettersson
2007-10-03 14:25 ` KAMEZAWA Hiroyuki
2007-10-04 11:56 ` Shi Weihua
2007-10-04 12:17 ` KAMEZAWA Hiroyuki
2007-10-04 12:33 ` Shi Weihua
2007-10-04 12:47 ` KAMEZAWA Hiroyuki
2007-10-03 8:06 Shi Weihua
2007-11-19 2:15 ` Shi Weihua
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4704C84C.3080804@cn.fujitsu.com \
--to=shiwh@cn.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mikpe@it.uu.se \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox