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.