Subject: segvguard [was: Re: CVS commit: src/sys/sys]
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Elad Efrat <elad@NetBSD.org>
List: tech-kern
Date: 11/22/2006 15:44:50
(at the request of hubertf@, I'm resending with a more appropriate
subject line.


YAMAMOTO Takashi wrote:

> please propose it explicitly.
> 
> 	- i don't think everyone read your paper. :)

:)

> 
> 	- as PF_MASKOS is a very limited resource,
> 	  i think it should be used carefully.

oh, certainly. it was just a quick way to pass data from elf header to
the kernel. any other way, of course, is welcome; it doesn't really
matter. :)

first, here's an excerpt from security(8) about segvguard:

   PaX Segvguard
     PaX Segvguard monitors the number of segfaults in a program
     per-user, in an attempt to detect on-going exploitation attempts
     and possibly prevent them.  One common attack PaX Segvguard can
     help mitigate is when an attacker tries to brute-force a function
     return address, when wanting to perform a return-to-lib attack.

     PaX Segvguard makes use of kernel memory, so use it wisely.  While
     it provides rate-limiting protections, it works on a per-program
     basis for keeping its records, meaning that irresponsible use may
     result in keeping track of all segfaults in the system, easily
     wasting all kernel memory.

     For this reason, it is highly recommended to have PaX Segvguard
     enabled explicitly only for network services etc.  Enabling PaX
     Segvguard explicitly works like this:

           # paxctl +G /usr/sbin/sshd

     However, a global knob is still provided, for use in strict
     environments with no local users (some network appliances, embedded
     devices, firewalls, etc.):

           # sysctl -w security.pax.segvguard.global=1

     PaX Segvguard can be configured to work in your preferred way.  For
     example, watching for 5 segfaults from the same user in a
     time-frame of 60 seconds:

           # sysctl -w security.pax.segvguard.max_crashes=5
           # sysctl -w security.pax.segvguard.expiry_timeout=60

     The number of seconds a user will be suspended from running the
     culprit program is also configurable.  For example, 10 minutes seem
     like a sane setting:

           # sysctl -w security.pax.segvguard.suspend_timeout=600

     Explicitly disabling PaX Segvguard can be done like this:

           # paxctl +g /bin/ls


segvguard makes most sense when used in conjunction with aslr, because
that's when brute-forcing return addresses is most likely to take place.

proper credit: segvguard was first introduced in a paper written by
Nergal in phrack 58:
http://artofhacking.com/files/phrack/phrack58/P58-0X04.TXT
also mentioned in:
http://artofhacking.com/files/phrack/phrack59/P59-0X09.TXT
(by an anonymous author)

the implementation I commited provides the very basic functionality; in
addition to obvious changes to kern_pax.c to provide the back-end, all
it adds are hooks in signal delivery and execve() to catch SIGSEGV and
prevent (re-)spawning of culprit processes. again, this is *very*
initial, it's just to get the work in-tree. :)

-e.

-- 
Elad Efrat