[PATCH] Collect more inode information during syscall processing.
authorAmy Griffis <amy.griffis@hp.com>
Thu, 3 Nov 2005 16:00:25 +0000 (16:00 +0000)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 20 Mar 2006 19:08:53 +0000 (14:08 -0500)
This patch augments the collection of inode info during syscall
processing. It represents part of the functionality that was provided
by the auditfs patch included in RHEL4.

Specifically, it:

- Collects information for target inodes created or removed during
  syscalls.  Previous code only collects information for the target
  inode's parent.

- Adds the audit_inode() hook to syscalls that operate on a file
  descriptor (e.g. fchown), enabling audit to do inode filtering for
  these calls.

- Modifies filtering code to check audit context for either an inode #
  or a parent inode # matching a given rule.

- Modifies logging to provide inode # for both parent and child.

- Protect debug info from NULL audit_names.name.

[AV: folded a later typo fix from the same author]

Signed-off-by: Amy Griffis <amy.griffis@hp.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c
fs/open.c
fs/xattr.c
include/linux/audit.h
include/linux/fsnotify.h
kernel/auditsc.c

index f6619af..51cfc9c 100644 (file)
@@ -1353,6 +1353,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
                return -ENOENT;
 
        BUG_ON(victim->d_parent->d_inode != dir);
+       audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino);
 
        error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
        if (error)
index 70e0230..7051000 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -27,6 +27,7 @@
 #include <linux/pagemap.h>
 #include <linux/syscalls.h>
 #include <linux/rcupdate.h>
+#include <linux/audit.h>
 
 #include <asm/unistd.h>
 
@@ -626,6 +627,8 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
        dentry = file->f_dentry;
        inode = dentry->d_inode;
 
+       audit_inode(NULL, inode, 0);
+
        err = -EROFS;
        if (IS_RDONLY(inode))
                goto out_putf;
@@ -775,7 +778,10 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
 
        file = fget(fd);
        if (file) {
-               error = chown_common(file->f_dentry, user, group);
+               struct dentry * dentry;
+               dentry = file->f_dentry;
+               audit_inode(NULL, dentry->d_inode, 0);
+               error = chown_common(dentry, user, group);
                fput(file);
        }
        return error;
index 80eca7d..e416190 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/syscalls.h>
 #include <linux/module.h>
 #include <linux/fsnotify.h>
+#include <linux/audit.h>
 #include <asm/uaccess.h>
 
 
@@ -234,12 +235,15 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
              size_t size, int flags)
 {
        struct file *f;
+       struct dentry *dentry;
        int error = -EBADF;
 
        f = fget(fd);
        if (!f)
                return error;
-       error = setxattr(f->f_dentry, name, value, size, flags);
+       dentry = f->f_dentry;
+       audit_inode(NULL, dentry->d_inode, 0);
+       error = setxattr(dentry, name, value, size, flags);
        fput(f);
        return error;
 }
@@ -458,12 +462,15 @@ asmlinkage long
 sys_fremovexattr(int fd, char __user *name)
 {
        struct file *f;
+       struct dentry *dentry;
        int error = -EBADF;
 
        f = fget(fd);
        if (!f)
                return error;
-       error = removexattr(f->f_dentry, name);
+       dentry = f->f_dentry;
+       audit_inode(NULL, dentry->d_inode, 0);
+       error = removexattr(dentry, name);
        fput(f);
        return error;
 }
index fd65078..739b954 100644 (file)
@@ -260,7 +260,20 @@ extern void audit_syscall_entry(struct task_struct *task, int arch,
 extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
 extern void audit_getname(const char *name);
 extern void audit_putname(const char *name);
-extern void audit_inode(const char *name, const struct inode *inode, unsigned flags);
+extern void __audit_inode(const char *name, const struct inode *inode, unsigned flags);
+extern void __audit_inode_child(const char *dname, const struct inode *inode,
+                               unsigned long pino);
+static inline void audit_inode(const char *name, const struct inode *inode,
+                              unsigned flags) {
+       if (unlikely(current->audit_context))
+               __audit_inode(name, inode, flags);
+}
+static inline void audit_inode_child(const char *dname, 
+                                    const struct inode *inode, 
+                                    unsigned long pino) {
+       if (unlikely(current->audit_context))
+               __audit_inode_child(dname, inode, pino);
+}
 
                                /* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
@@ -283,7 +296,10 @@ extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
 #define audit_syscall_exit(t,f,r) do { ; } while (0)
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
+#define __audit_inode(n,i,f) do { ; } while (0)
+#define __audit_inode_child(d,i,p) do { ; } while (0)
 #define audit_inode(n,i,f) do { ; } while (0)
+#define audit_inode_child(d,i,p) do { ; } while (0)
 #define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
 #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
 #define audit_get_loginuid(c) ({ -1; })
Simple merge
Simple merge