From owner-freebsd-bugs@FreeBSD.ORG Mon Mar 22 08:00:36 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 13A7916A4D0 for ; Mon, 22 Mar 2004 08:00:36 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 06F5043D1D for ; Mon, 22 Mar 2004 08:00:36 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) i2MG0Zbv039856 for ; Mon, 22 Mar 2004 08:00:35 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.10/8.12.10/Submit) id i2MG0ZcM039855; Mon, 22 Mar 2004 08:00:35 -0800 (PST) (envelope-from gnats) Resent-Date: Mon, 22 Mar 2004 08:00:35 -0800 (PST) Resent-Message-Id: <200403221600.i2MG0ZcM039855@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, gordon Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3626B16A4CE for ; Mon, 22 Mar 2004 08:00:03 -0800 (PST) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1A39D43D3F for ; Mon, 22 Mar 2004 08:00:03 -0800 (PST) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.12.10/8.12.10) with ESMTP id i2MG0272074828 for ; Mon, 22 Mar 2004 08:00:02 -0800 (PST) (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.12.10/8.12.10/Submit) id i2MG02NC074827; Mon, 22 Mar 2004 08:00:02 -0800 (PST) (envelope-from nobody) Message-Id: <200403221600.i2MG02NC074827@www.freebsd.org> Date: Mon, 22 Mar 2004 08:00:02 -0800 (PST) From: gordon To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-2.3 Subject: kern/64573: mmap with PROT_NONE, but still could be read X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Mar 2004 16:00:36 -0000 >Number: 64573 >Category: kern >Synopsis: mmap with PROT_NONE, but still could be read >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Mar 22 08:00:35 PST 2004 >Closed-Date: >Last-Modified: >Originator: gordon >Release: FreeBSD current 5.2 >Organization: PDL >Environment: FreeBSD i386 >Description: I have ported a test program for LSB test suites to test the compatibility of mmap system call. As to Open Group Technical Standard System Interfaces and Headers, Issue 5, when mmap with PROT_NONE, the mapped pages should not be allowed to access. But as the program shows, the mapped page could still be read. Can anyone tell me how to solve this problem? #include #include #include #include #include #include #include #include #include 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); } >How-To-Repeat: The ported program is attached in the Full Description part. >Fix: >Release-Note: >Audit-Trail: >Unformatted: