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
The NetBSD Foundation, Inc.
System: NetBSD 8.99.14 NetBSD 8.99.14 (GENERIC) #213: Sat Apr 28 09:26:35 CEST 2018 amd64
Architecture: x86_64
Machine: amd64

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

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:

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

	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;


cc -Wall -O2 -pthread test.c


Home | Main Index | Thread Index | Old Index