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>