Subject: Re: systrace features?
To: Charles Blundell <cb@netbsd.org>
From: Niels Provos <provos@citi.umich.edu>
List: tech-security
Date: 09/29/2003 12:32:50
On Tue, Sep 23, 2003 at 04:40:03PM +0100, Charles Blundell wrote:
> Randomly cause system calls to fail.
>  * This can be used to explore code paths that may only be taken
>    rarely.  When used with automatic policy generation, this helps
>    the policy to converge on a programs actual behaviour.
> 
>    $ systrace -A cat /etc/myname
>    $ cp .systrace/bin_cat .systrace/bin_cat.orig
>    $ for x in $(jot 10); do systrace -A -r 10 cat /etc/myname; done
>    ...
>    $ diff -u .systrace/bin_cat.orig .systrace/bin_cat
> +	netbsd-fsread: filename eq "/usr/share/nls/C/libc.cat" then permit
> +	netbsd-fsread: filename eq "/usr/share/nls/nls.alias" then permit
> +	netbsd-fsread: filename eq "/<non-existent filename>: /usr/share/nls/libc/C" then permit
> +	netbsd-__sigprocmask14: permit
> +	netbsd-getpid: permit
> +	netbsd-kill: pidname eq "/bin/cat" and signame eq "SIGABRT" then permit
> +	netbsd-kill: pidname eq "<unknown>" and signame eq "SIGABRT" then permit
> +	netbsd-__sigaction_sigtramp: permit
> 
>    The last kill rule appears to be the result of getpid failing.
>    getpid() will never fail, so it seems to me that maybe systrace
>    should be told about system calls that cannot fail? The same
>    failure could occur in automatic mode, with some code like this:
> 	kill(getpid(), SIGKILL);
>    so if getpid returns -1, and the process is running as root...
>    other nasty things with get*id()

Fault injection to test error handling is a very useful.  However,
I do not think that it should be part of systrace proper.  Currently,
systrace already allows you to specify a separate frontend.  In the
past, I have written simple shell scripts to introduce random faults
in system calls using Systrace.  Just do something like

  systrace -g ./faultinjectionwrapper cat /etc/myname

and then have faultinjectionwrapper be a shell script that reads
from stdin and writes policy answers to stdout, for example:

#!/bin/ksh
IFS="_"
while read name
do
    if [ "$name" = "OKAY" ] ; then
        continue
    fi

    ISBREAK=`echo $name | grep -i "native.break"`
    if [ -z "$ISBREAK" ] ; then
        echo "permit"
    else
        NR=`expr $RANDOM % 100`
        if [[ "$NR" < "1" ]] ; then
            echo "Denying break" >&2
            echo "deny-now[enobufs]"
        else
            echo "permit-now"
        fi
    fi
done

> Terminating a process when a system call not in its policy is
> attempted (only for unsupervised processes.) May help with policy
> probing attacks, and the problem noted above with kill.

That may be useful.  A kill action by itself may be good, too.

Niels.