Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Mar 2004 00:28:29 +0800
From:      "hddai" <hddai@163.net>
To:        "freebsd-hackers" <freebsd-hackers@freebsd.org>
Subject:   mmap with PROT_NONE
Message-ID:  <20040322162658.9DBE443D2D@mx1.FreeBSD.org>

next in thread | raw e-mail | index | archive | help
Hi,all

I have got a problem.As the Open Group Technical Standard System Interfaces and Headers,Issue 5 says, when use mmap with PROT_NONE, the mapped pages should not be accessed. But I found they can still be read.
The following is a little program ported from LSB test suites. Can anyone tell me how to solve it?
thanks in advance.

Gordon


**********************mmap_test.c*************************************

#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>

static int vsrt_mmap_setup(void);
static void vsrt_mmapsig_fn(int);
static void vsrt_invalid_sig_fn(int);
static int vsrt_signal(int , void (*handler)(int));
static int vsrt_open_file(char* s, int flag, mode_t mode, int npages);
typedef struct {
		char	name[10];
		int	signal;
		int	flags;
	} vsrt_siglst;
static vsrt_siglst	vsrt_signals[] = {
		{ "SIGFPE",	SIGFPE,		0 },
		{ "SIGILL",	SIGILL,		0 },
	};
#define	VSRT_NUM_SIGNALS	(sizeof(vsrt_signals) / sizeof(vsrt_siglst))
#define VSRT_PROT_ALL	(mode_t)(S_IRWXU|S_IRWXG|S_IRWXO)
static char* test_file = "./dhd";
static int vsrt_got_sigsegv = 0;
static int vsrt_got_sigbus = 0;
static int vsrt_got_sig = 0;
static int vsrt_setjmp_called = 0;
static unsigned long vsrt_pgsz, vsrt_ipgsz;
static sigjmp_buf vsrt_env;	
static struct sigaction Sigaction;

main()
{
	int	fd, err;
	pid_t	pid;
	int *addr;
	volatile int i;
	
	if (vsrt_mmap_setup() == -1){
		printf("Setup error!\n");
		return;
	}
	fd = vsrt_open_file(test_file, O_RDWR, VSRT_PROT_ALL, 2);
	if (fd == -1){
		printf("Error in open file\n");
		return;
	}
	if ((addr = (int *)mmap(0, vsrt_pgsz, PROT_NONE, MAP_SHARED, fd, (off_t)vsrt_pgsz)) == (int *) (-1)) {
		err = errno;
		printf("mmap failed, errno = %d \n", err);
		(void)close(fd);
		(void)unlink(test_file);
		return;
	}

	
	if ((pid = fork()) == 0){
		vsrt_setjmp_called = 1;

		if(sigsetjmp(vsrt_env,1) ==0)
			i = *addr;

		if (!(vsrt_got_sigsegv || vsrt_got_sigbus)) {
			printf("Mapped page could be accessed\n");
			exit(1);
		}
		else printf("Mapped page could not be accessed\n");
		exit (0);
	}
	else if (pid == -1){
		printf("fork failed\n");
		exit(0);
	}
	else	wait((int *)0);	
	close(fd);
	munmap((void*) addr, (size_t)vsrt_pgsz);
	unlink(test_file);
} 

int vsrt_mmap_setup(void) {
	int	i;
	
	if ((vsrt_pgsz = sysconf(_SC_PAGESIZE)) == -1) {
		printf("Error to get pagesize\n");
		return -1;
	}
	vsrt_ipgsz = vsrt_pgsz/sizeof(int);
	vsrt_got_sigsegv = vsrt_got_sigbus = vsrt_got_sig = 0;
	for (i = 0; i < VSRT_NUM_SIGNALS; i++) {
		if (vsrt_signal(vsrt_signals[i].signal, &vsrt_invalid_sig_fn) == -1)  return -1;
	}
	if (vsrt_signal(SIGSEGV, vsrt_mmapsig_fn) == -1) return -1;
	if (vsrt_signal(SIGBUS, vsrt_mmapsig_fn) == -1)	return -1;
	return 0;
}

int vsrt_signal(int sig, void (*handler)(int))
{
	int	rval;
	rval = sigemptyset(&(Sigaction.sa_mask));
	if (rval == -1) {
		printf("Error to sigemptyset\n");
		return -1;
	}
	Sigaction.sa_handler = handler;
	Sigaction.sa_flags = 0;
	rval = sigaction(sig,&Sigaction,(struct sigaction *)NULL);
	if (rval == -1) {
		printf("Error in sigaction\n");
		return -1;
	}
	return 0;
}

static void vsrt_invalid_sig_fn(int s)
{
	int i;
	for (i = 0; i < VSRT_NUM_SIGNALS; i++) {
		if (s == vsrt_signals[i].signal) {
			printf("Invalid signal: %d(%s) received\n", s, vsrt_signals[i].name);
			return;
		}
	}
}

static void vsrt_mmapsig_fn(int s)
{
	if (s == SIGSEGV)	vsrt_got_sigsegv++;
	else if (s == SIGBUS) vsrt_got_sigbus++;
	vsrt_got_sig++;
	if (vsrt_setjmp_called) {
		vsrt_setjmp_called = 0;
		siglongjmp(vsrt_env, 1);
	}
}

int vsrt_open_file(char* s, int flag, mode_t mode, int npages)
{
	int fd, *buf, i, j;
	unlink(s);
	if ((fd = open(s, (O_RDWR|O_CREAT|O_TRUNC), (mode_t)(S_IRWXU|S_IRWXG|S_IRWXO))) == -1) {
		printf("open() failed, errno = %d \n", errno);
		return -1;
	}
	if ((buf = (int *)malloc(sizeof(int) * vsrt_ipgsz * npages)) == NULL) {
		printf("malloc() failed, errno = %d \n", errno);
		return -1;
	}
	for (j = 0; j < vsrt_ipgsz*npages; j += sizeof(buf)/sizeof(buf[0])) {
		for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i++)	buf[i] = i + j;
		if (write(fd, (void*)buf, sizeof(buf)) != sizeof(buf)) {
			printf("write() failed, errno = %d \n", errno );
			return -1;
		}
	}
	(void)close(fd);
	if (chmod(s, mode) == -1) {
		printf("chmod() failed, errno = %d \n", errno);
		return -1;
	}
	if ((fd = open(s, flag)) == -1) {
		printf("open() failed, errno = %d \n", errno);
		return -1;
	}
	return (fd);
}




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040322162658.9DBE443D2D>