login
Header Space

 
 

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

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: KAMEZAWA Hiroyuki <kamezawa.hiroyu@...>
Cc: Mikael Pettersson <mikpe@...>, <linux-kernel@...>
Date: Thursday, October 4, 2007 - 7:56 am

KAMEZAWA Hiroyuki wrote::

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 <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 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


-
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [PATCH 1/3] signal(i386): alternative signal stack wrapa..., KAMEZAWA Hiroyuki, (Wed Oct 3, 10:25 am)
Re: [PATCH 1/3] signal(i386): alternative signal stack wrapa..., Shi Weihua, (Thu Oct 4, 7:56 am)
speck-geostationary