NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/53232: mprotect() modifications of stack pages



>Number:         53232
>Category:       kern
>Synopsis:       mprotect() modifications of stack pages
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Apr 29 17:30:00 +0000 2018
>Originator:     Martin Husemann
>Release:        NetBSD 8.99.14
>Organization:
The NetBSD Foundation, Inc.
>Environment:
System: NetBSD seven-days-to-the-wolves.aprisoft.de 8.99.14 NetBSD 8.99.14 (GENERIC) #213: Sat Apr 28 09:26:35 CEST 2018 martin%seven-days-to-the-wolves.aprisoft.de@localhost:/work/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:

The following program simulates thread initialization of rust programs.
It fails in -current, which breaks all rustc compiled
programs.

It is not obvious to me if this is a kernel bug (and we actively
prevent modifications close to the kernel internal red page).
In that case we should just offset the rustc guard page by
one page.

Here is the test program:

--8<--
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/mman.h>

int
main(void)
{
	int rv;
	void *start, *guard, *addr;
	size_t size, page_size;
	pthread_attr_t attr = { 0 };

	page_size = sysconf(_SC_PAGESIZE);

	rv = pthread_getattr_np(pthread_self(), &attr);
	if (rv) err(EXIT_FAILURE, "pthread_getattr_np");

	rv = pthread_attr_getstack(&attr, &start, &size);
	if (rv) err(EXIT_FAILURE, "pthread_attr_getstack");

	guard = (void*)((uintptr_t)start + page_size);

	printf("stack: %p, stack size: %zx, guard page: %p\n", start, size, guard);

	addr = mmap(guard, page_size, PROT_NONE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
	if (addr != guard)
		err(EXIT_FAILURE, "mmap did not return guard address: %p", addr);

	rv = mprotect(addr, page_size, PROT_READ|PROT_WRITE);
	if (rv)
		err(EXIT_FAILURE, "could not make guard page writable: rv: %d", rv);

	return 0;
}
-->8--

>How-To-Repeat:

cc -Wall -O2 -pthread test.c
./a.out

>Fix:
n/a



Home | Main Index | Thread Index | Old Index