Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73241ccc authored by Amy Griffis's avatar Amy Griffis Committed by Al Viro
Browse files

[PATCH] Collect more inode information during syscall processing.



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: default avatarAmy Griffis <amy.griffis@hp.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent f38aa942
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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)
+7 −1
Original line number Diff line number Diff line
@@ -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;
+9 −2
Original line number Diff line number Diff line
@@ -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;
}
+17 −1
Original line number Diff line number Diff line
@@ -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; })
+5 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@

#include <linux/dnotify.h>
#include <linux/inotify.h>
#include <linux/audit.h>

/*
 * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir
@@ -45,6 +46,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
	if (source) {
		inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL);
	}
	audit_inode_child(old_name, source, old_dir->i_ino);
	audit_inode_child(new_name, target, new_dir->i_ino);
}

/*
@@ -74,6 +77,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
{
	inode_dir_notify(inode, DN_CREATE);
	inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name);
	audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
}

/*
@@ -84,6 +88,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
	inode_dir_notify(inode, DN_CREATE);
	inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, 
				  dentry->d_name.name);
	audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
}

/*
Loading