VFS hooks analysis (pass 1)
Timothy R. Chavez
tinytim at us.ibm.com
Mon Aug 29 22:12:01 UTC 2005
On Friday 26 August 2005 17:13, Amy Griffis wrote:
> Hello,
Hey Amy, great work. Well organized. Thanks. Comments below.
>
> I've been investigating audit's needs for VFS hook placement, to
> determine whether audit would require additional events or additional
> information about events, other than what is currently provided by
> Inotify.
>
> I've written up my findings in hopes that some of you who may be more
> familiar with the situation than I can correct my mistakes, and that
> we can all be on the same page with regard to audit's needs.
>
> At this point, I haven't addressed the issue of race conditions. For
> the purpose of the first pass, I make the assumption that the current
> fsnotify hook placement is sufficient. I'll address the possibility
> of race conditions in a second pass.
>
> Background:
>
> The purpose of the VFS hooks is to capture information about an
> object's identity. In this implementation, identity means inode and
> name. Identity information is needed for filtering and for log record
> detail.
>
> To narrow the field, I limited the set of syscalls to those which are
> defined by CAPP as security-relevant and are also filesystem-related.
> I believe this is the correct list:
>
> sys_access
> sys_chdir
> sys_chmod
> sys_chown
> sys_creat
> sys_execve
> sys_fchmod
> sys_fchown
> sys_fremovexattr
> sys_fsetxattr
> sys_lchown
> sys_link
> sys_lremovexattr
> sys_lsetxattr
> sys_mkdir
> sys_mknod
> sys_mount
> sys_open
> sys_removexattr
> sys_rename
> sys_rmdir
> sys_setxattr
> sys_swapon
> sys_symlink
> sys_truncate
> sys_unlink
> sys_utime(s)
>
> Available Object Identity Info:
>
> The upstream audit code uses getname() and path_lookup() hooks to
> collect object identity information during syscall processing. This
> is sufficient for the following syscalls:
>
> sys_access
> sys_chdir
> sys_chmod
> sys_chown
> sys_execve
> sys_lchown
> sys_link
> sys_lremovexattr
> sys_lsetxattr
> sys_removexattr
> sys_setxattr
> sys_swapon
> sys_truncate
> sys_utime(s)
>
Here's my thinking. It'd be nice to have a complete set of Inotify hooks
that map to specific Inotify events (IN_*). Thus, even though the above
syscalls may be sufficiently covered by the hook placements in the
getname() and path_lookup() functions, I think we should split them out
into seperate Inotify hooks. This gives us the ability to consistently audit
a file system object based on a set of events (which is ammenable to
Steve's log size reduction campaign :-)). This also makes the overall
API cleaner and more coherent.
The administrator would then be able to do something like this,
auditctl -w /this/path/watch_this_inode -E create,open,close,write
> Lacking Object Identity Info:
>
> The information audit needs isn't available when path_lookup is called
> with LOOKUP_PARENT, or when getname/path_lookup are not called at all.
> In these situations, audit needs more VFS hooks to get the necessary
> information.
>
> Attribute Changes:
>
> The getname/path_lookup hooks are never called for these syscalls:
>
> sys_fchmod
> sys_fchown
> sys_fremovexattr
> sys_fsetxattr
>
> The fsnotify_change() and fsnotify_xattr() hooks capture the relevant
> dentry, so the dentry's name & inode could be passed to the event
> callback.
>
> Mounts:
>
> For sys_mount, audit does not currently capture the pathname for the
> device. This is because getname is not called before path_lookup. We
> could modify audit_inode() to save the name from path_lookup for
> "nameless" inodes. Note the FIXME in audit_inode().
>
> The rest of the syscalls are mostly lacking information due to
> path_lookup being called with LOOKUP_PARENT.
>
> Created Objects:
>
> sys_creat
> sys_mkdir
> sys_mknod
> sys_open
>
> The fsnotify_create() and fsnotify_mkdir() hooks have the same
> placement as audit_notify_watch(), but audit needs the dentry's inode.
> The fsnotify hooks could be modified to capture the dentry, instead of
> just the dentry->d_name.name.
>
> Removed Objects:
>
> sys_rmdir
> sys_unlink
>
> The fsnotify_inoderemove() hook provides the inode, but see note below
> on capturing attempted removals.
>
> Symlinks:
>
> sys_symlink
>
> The inodes for the target path and symlink are not available from the
> getname/path_lookup hoooks. The PATH records do not indicate which
> name is the symlink. Maybe this isn't necessary since you can tell
> from the syscall args.
>
> As previously mentioned, the fsnotify_create() hook could be modified
> to capture the dentry instead of the dentry->d_name.name. This would
> provide audit with the symlink's inode.
>
> I haven't found a good way to capture the target inode. We don't do
> it in the current implementation, which means we don't log events when
> someone makes a symlink to a watched inode or pathname. It seems like
> we should, though.
>
> Renames:
>
> sys_rename
>
> The inode for the relevant object is not available from the
> getname/path_lookup hooks. There is also no way to indicate the old
> name versus the new name, other than by the syscall args.
>
> The fsnotify_move() hook could be modified to capture the old and new
> dentrys, instead of just the names, which would provide audit with the
> inode (twice). Inotify provides separate to/from events.
>
> Capturing Unsuccessful Attempts:
>
> CAPP dictates that audit must capture unsuccessful attempts from open,
> rename, truncate, and unlink. The open and truncate calls are a
> non-issue, the inode is obtained from the path_lookup hook.
>
> The rename and unlink calls present the problem. Since the inode
> wouldn't be captured unless the rename/remove was successful, an
> inode-based filter wouldn't catch unsuccessful attempts.
>
> Summary:
>
> To summarize, I haven't found a situation requiring the current
> permission() and exec_permission_lite() hooks.
Good. I'm of the opinion that we should stay away from catch-all hooks.
Especially since we now have the benefit of Inotify and its prolific use
of file system hooks.
>
> The issues seem to be with symlinks and logging unsuccessful
> rename/remove attempts.
>
> I can think of three possible solutions for the latter:
>
> (1) Require filters based on filenames to capture unsuccessful
> attempts. This seems undesirable.
>
> (2) Have an audit-specific hook in may_delete(), as is currently
> done, but have it tie in to inode-based filters as well.
>
> (3) Request an additional Inotify event that would not be included
> in IN_ALL_EVENTS, so wouldn't impact Inotify's other users.
>
> I think 2 or 3 are our best options, with the answer likely depending
> on what Inotify is willing to add. It is probably doable to add
> audit-specific hooks if they are few and if Inotify isn't interested.
>
> I do not yet have a solution for capturing the target inode from a
> symlink operation. However since it's not currently done, maybe it
> isn't a hard requirement?
>
> I'd appreciate any comments on my analysis.
>
> Thanks,
> Amy
Thank you, this is really quite helpful.
-tim
More information about the Linux-audit
mailing list