From owner-freebsd-hackers Tue Mar 4 03:42:49 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id DAA17426 for hackers-outgoing; Tue, 4 Mar 1997 03:42:49 -0800 (PST) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id DAA17420 for ; Tue, 4 Mar 1997 03:42:43 -0800 (PST) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.3/8.6.9) id WAA06944; Tue, 4 Mar 1997 22:32:08 +1100 Date: Tue, 4 Mar 1997 22:32:08 +1100 From: Bruce Evans Message-Id: <199703041132.WAA06944@godzilla.zeta.org.au> To: terry@lambert.org, wpaul@skynet.ctr.columbia.edu Subject: Re: Removing execute privs from stack pages Cc: hackers@FreeBSD.org Sender: owner-hackers@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk >> I've got a question for you VM/i386 gurus out there. Recently, somebody >> showed me a script for Solaris/SPARC to short-circuit buffer overflow >> security holes by removing execute access from the user stack pages. >> ... >> My question is: can this sort of thing be done with FreeBSD/i386? > >The short answer: "no". Actually, the short answer is "no/yes". i386's have funky segment-level execute protection. >The long answer: there is no distinction between "readable" and >"executable" in the hardware mapping interpretation. You *might* >be able to ensure non-writability -- but not on all hardware, >since a write fault is not generated in kernel space except on newer >processors, and then only if the bit is enabled (write fault handling >on i386 is typically emulated in the copyin/copyout). This would >require execution time overhead to force non-contiguity of the mapping >boundry so that it could be determined if the page was code or data >at fault time... a lot of overhead for little protection. The plain-i386 write protection flaw is irrelevant. >Even with this protection, obviously "su" must be able to invoke a >shell in the success case. The stack overflow for the return >address could easily point the return address to the valid exec >code instead of returning and going through the compare which fails >and aborts the exec. So you would also have to be sure that no >code existed, such that if it were interpreted on any particular >byte boundry, it would result in a shell. It's easier than that. You just need to make the return address point to the right place in execve() ... >Frankly, I wonder how LISP and FORTH can run on such a system. I think they would have to do system calls to map pages for execution. Even dynamically linked C code would need this. There would be some security if the mapping were refused for setuid processes. Bruce