On Wed, Aug 25, 2004 at 05:44:46PM +0200, Olaf Kirch wrote:
| Hi,
|
| On Wed, Aug 25, 2004 at 09:53:44AM -0500, Jonathan Abbey wrote:
| > | You may want to use auditing with subdomain, or you may even want to use
| > | it without any security modules at all (because frankly, SElinux sucks
| > | performance-wise, and it's not terribly stable yet either)
| >
| > Rik's audit work can be used without the bulk of SELinux, as I
| > understand the implementation?
|
| I seriously hope it can.
|
| > The audit daemon's efficiency has been increased by a factor of 10 or
| > so in the recent code, the username/groupname caching being part of
| > that. There's still more work to do, though, particularly at the
| > kernel/userland interface.
|
| I seriously believe that filtering in the user land is wrong. At most,
| the daemon should shovel fully cooked records from the kernel into
| the audit trail files and potentially other consumers (such as IDSs).
Snare does do preliminary filtering in the kernel, deciding which
syscall audit records should be passed to the userland based on what
objectives are specified to the daemon.. i.e., if you don't specify
any filters on open(), no open syscall audit record will be passed to
the daemon.
| For performance reasons, filtering should happen in the kernel module, so
| we avoid costly memory allocations and kernel-user land copying.
To be sure. The big win for Snare in doing userland filtering is the
ability to apply regular expressions, but as long as you have support
for prefix and suffix matching in the kernel, you might not gain all
that much for the extra cost, flexible though it is for the user.
| > The biggest dissatisfaction we have with the 2.6.6 audit framework is
| > that syscall arguments are not logged in the event of early abort of
| > syscall processing due to a lack of capabilities, etc. We read NISPOM
| > Ch. 8 as requiring detailed logging of failed attempts to access
| > "security-relevant objects". A non-root user attempting to do root
| > actions like 'chroot' is a pretty silly user, but NISPOM would like to
| > know that sort of thing.
|
| Same for CAPP. I'd have to go and see how hard it would be to adapt
| the laus module to this infrastructure.
|
| > Therefore, we would prefer to see a mechanism in which all auditable
| > parameters are copied to kernel space up front, and that the syscalls
| > would then be written to use the pre-copied parameters rather than
| > doing direct mapping from user space. There would obviously be
| > certain kinds of parameters that could not reasonably be audited in
| > such a framework, but that will be true in any prospective auditing
| > system.
|
| Not sure if I understand what you intend to do here. Some audit
| implementations I looked at created wrapper functions that copied
| arguments from user space and did a set_fs(KERNEL_DS). This is obviously
| a simple way of doing it but it creates security problems if you audit
| system calls that pass structs with pointers in them. That way, you could
| never audit ioctls (besides, there are many ioctls that don't follow the
| convention of including call direction and argument size in the ioctl
| number, so you wouldn't know the argument size beforehand).
Well, right.. I expect that there would have to be context sensitive
code to decide which arguments should be considered auditable. If we
can't get a clean snapshot of a syscall's arguments for such practical
reasons, then the auditing framework should be cognizant of that.
| > | Maybe there's even a way we can tap into copy_from_user pretty much
| > | the same way Rik taps into getname.
| >
| > Hmm.. we could perhaps add a identifying tag as an additional
| > parameter to copy_from_user, so as to allow tracking of multiple
| > parameters copied from user space, but that still wouldn't support
| > full auditing of preemptively rejected syscalls.
|
| Why not? The basic idea is simple.
|
| - intercept system call on entry, copy arguments from registers
| to some internal per-process structure.
| - in copy_from_user, check the source pointer against all
| arguments in above structure
| - if we have a match, kmalloc a suitable chunk of memory and
| copy the argument
| - on the way out, call the audit filter to find out if we need
| to audit the syscall. If yes, build the audit record.
| - When building the audit record, check if we have a copy of
| the argument. If not, we aborted early, so get the argument
| now.
Why kmalloc/copy in copy_from_user when we've already copied the
arguments from registers to a per-process structure?
| This is mostly generic; it doesn't even involve selinux.
| All you need is a table mapping system call numbers to argument types,
| the way we did in laus. This allows you to audit _any_ system call
| without having to touch each and every kernel function.
| (You need some special cases, because some arguments need to be copied on
| their way in, such as the argv array in execve - when we return, argv
| no longer points to anything useful)
Right.
| The down side is obviously that you have to put a branch into copy_from_user,
| which many people will not like for performance reasons. Obviously, some
| clever magic is needed here.
Only if you are running with audit enabled, yes? I don't know how
often copy_from_user is used outside of the syscall argument
processing case, but if there's a distinction to be drawn between
conceivably auditable use and never-auditable use, one could split
copy_from_user and provide an audit-enabled variant for syscalls.
| Another extension along the same line would be to add a hook to the namei
| functions so that we get the dentry and thereby the resolved path, rather
| than some more or less useless string.
Right.
Thanks,
Jon
| Olaf
| --
| Olaf Kirch | The Hardware Gods hate me.
| okir(a)suse.de |
| ---------------+
--
-------------------------------------------------------------------------------
Jonathan Abbey jonabbey(a)arlut.utexas.edu
Applied Research Laboratories The University of Texas at Austin
GPG Key: 71767586 at keyserver
pgp.mit.edu,
http://www.ganymeta.org/workkey.gpg