Skip to contentSkip to conversation

file system auditing

RFC PATCH In review Timothy R. Chavez 1 participant 3 messages Apr 5, 2005 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/2 file system auditing

Hello,

The audit subsystem is currently incapable of auditing a file system object based on its location and name.  This is critical for auditing well-defined and security-relevant locations such as /etc/shadow, where the file is re-created on each transaction, and cannot rely on the (device, inode)-based filters to ensure persistence of auditing across transactions. This patch adds the necessary functionality to the audit subsystem and VFS to support file system auditing in which an object is audited based on its location and name. This work is being done to make the audit subsystem compliant with Common Criteria's Controlled Access Protection Profile (CAPP) specification.

The patch has been split in two for RFC.

[PATCH 1/2]
The first patch consists of the file system hooks and appears at the bottom of this message preceded by brief explanations of each hook.  The quoted terminology is defined in the high-level overview of the design that's been included with the second patch in the next message.

[PATCH 2/2]
The second patch consists of the file system auditing implementation preceded by a high-level overview of the design.

The entire patch was diffed against linux-2.6.11-rc2-mm1

-tim

----

1.  Setup

Placement in fs/inode.c

audit_inode_alloc()/audit_inode_free():
These hooks are responsible for allocating and deallocating inode audit data.

2.  Management

Management of "watches" starts at the dentry level.

Placement in fs/dcache.c

Initial setup:

d_instantiate()/d_splice_alias() :
These hooks cover initial audit setup for inodes that are newly created and for existing inodes when they are first looked up, prior to becoming accessible via the dcache.

Update:

__d_lookup():
This hook covers updating the inode audit data if necessary upon subsequent lookups when the inode is already accessible via dcache, both to reflect removal of "watches" and to handle changes in state since the initial setup.

d_move():
This hook covers resetting the inode audit data and updating it accordingly post-move.

Deletion:

dentry_iput():
This hook covers resetting the inode audit data if the dentry being deleted is at a "watch point".

3.  Notification

Any time we access a "watched" object we are auditable.  These hooks are used to notify the audit subsystem of relevant access.

Placement in fs/namei.c.

Permissions:

permission()/exec_permission_lite():
Notify the audit subsystem when a "watched" object is consulted about permissions requirements.

Creation:

vfs_link()/symlink()/create()/mkdir()/mknod():
Notify the audit subsystem when an object has successfully manifested at a "watch point".

Deletion:

may_delete() [vfs_unlink()/rmdir()]:
Notify the audit subsystem when an object attempts to leave a "watch point". This hook appears in may_delete() after its been determined the object has an inode.

Note:  We are unable to use may_create() in a similar fashion to may_delete() because the object should not have an inode associated with it yet.

Rename:

may_delete(),vfs_rename_other()/rename_dir():
Notify the audit subsystem when an object has been moved out of a "watch point" using the may_delete() hook.  Notify the audit subsystem when an object already exists at our destination and our destination is a "watch point".  Notify the audit subsystem when an object moves in to a "watch point" using the vfs_rename_other/rename_dir() hooks.

fs/dcache.c +9 -0
diff -Nurp linux-2.6.12-rc2-mm1/fs/dcache.c linux-2.6.12-rc2-mm1~audit/fs/dcache.c
@@ -32,6 +32,7 @@
 #include <linux/seqlock.h>
 #include <linux/swap.h>
 #include <linux/bootmem.h>
+#include <linux/audit.h>
 
 /* #define DCACHE_DEBUG 1 */
 
@@ -97,6 +98,7 @@ static inline void dentry_iput(struct de
 {
 	struct inode *inode = dentry->d_inode;
 	if (inode) {
+		audit_attach_watch(dentry, 1);
 		dentry->d_inode = NULL;
 		list_del_init(&dentry->d_alias);
 		spin_unlock(&dentry->d_lock);
@@ -802,6 +804,7 @@ void d_instantiate(struct dentry *entry,
 	if (inode)
 		list_add(&entry->d_alias, &inode->i_dentry);
 	entry->d_inode = inode;
+	audit_attach_watch(entry, 0);
 	spin_unlock(&dcache_lock);
 	security_d_instantiate(entry, inode);
 }
@@ -978,6 +981,7 @@ struct dentry *d_splice_alias(struct ino
 		new = __d_find_alias(inode, 1);
 		if (new) {
 			BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
+			audit_attach_watch(new, 0);
 			spin_unlock(&dcache_lock);
 			security_d_instantiate(new, inode);
 			d_rehash(dentry);
@@ -987,6 +991,7 @@ struct dentry *d_splice_alias(struct ino
 			/* d_instantiate takes dcache_lock, so we do it by hand */
 			list_add(&dentry->d_alias, &inode->i_dentry);
 			dentry->d_inode = inode;
+			audit_attach_watch(dentry, 0);
 			spin_unlock(&dcache_lock);
 			security_d_instantiate(dentry, inode);
 			d_rehash(dentry);
@@ -1090,6 +1095,7 @@ struct dentry * __d_lookup(struct dentry
 		if (!d_unhashed(dentry)) {
 			atomic_inc(&dentry->d_count);
 			found = dentry;
+			audit_attach_watch(found, 0);
 		}
 		spin_unlock(&dentry->d_lock);
 		break;
@@ -1299,6 +1305,8 @@ void d_move(struct dentry * dentry, stru
 		spin_lock(&target->d_lock);
 	}
 
+	audit_attach_watch(dentry, 1);
+
 	/* Move the dentry to the target hash queue, if on different bucket */
 	if (dentry->d_flags & DCACHE_UNHASHED)
 		goto already_unhashed;
@@ -1332,6 +1340,7 @@ already_unhashed:
 		list_add(&target->d_child, &target->d_parent->d_subdirs);
 	}
 
+	audit_attach_watch(dentry, 0);
 	list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
 	spin_unlock(&target->d_lock);
 	spin_unlock(&dentry->d_lock);
fs/inode.c +5 -1
diff -Nurp linux-2.6.12-rc2-mm1/fs/inode.c linux-2.6.12-rc2-mm1~audit/fs/inode.c
@@ -22,6 +22,7 @@
 #include <linux/cdev.h>
 #include <linux/bootmem.h>
 #include <linux/inotify.h>
+#include <linux/audit.h>
 
 /*
  * This is needed for the following functions:
@@ -140,9 +141,11 @@ static struct inode *alloc_inode(struct 
 		inode->i_bdev = NULL;
 		inode->i_cdev = NULL;
 		inode->i_rdev = 0;
+		inode->i_audit = NULL;
 		inode->i_security = NULL;
 		inode->dirtied_when = 0;
-		if (security_inode_alloc(inode)) {
+		if (audit_inode_alloc(inode) || security_inode_alloc(inode)) {
+			audit_inode_free(inode);
 			if (inode->i_sb->s_op->destroy_inode)
 				inode->i_sb->s_op->destroy_inode(inode);
 			else
@@ -180,6 +183,7 @@ void destroy_inode(struct inode *inode) 
 {
 	if (inode_has_buffers(inode))
 		BUG();
+	audit_inode_free(inode);
 	security_inode_free(inode);
 	if (inode->i_sb->s_op->destroy_inode)
 		inode->i_sb->s_op->destroy_inode(inode);
fs/namei.c +13 -0
diff -Nurp linux-2.6.12-rc2-mm1/fs/namei.c linux-2.6.12-rc2-mm1~audit/fs/namei.c
@@ -225,6 +225,8 @@ int permission(struct inode *inode, int 
 {
 	int retval, submask;
 
+	audit_notify_watch(inode, mask);
+
 	if (mask & MAY_WRITE) {
 		umode_t mode = inode->i_mode;
 
@@ -358,6 +360,8 @@ static inline int exec_permission_lite(s
 	if (inode->i_op && inode->i_op->permission)
 		return -EAGAIN;
 
+	audit_notify_watch(inode, MAY_EXEC);
+
 	if (current->fsuid == inode->i_uid)
 		mode >>= 6;
 	else if (in_group_p(inode->i_gid))
@@ -1172,6 +1176,8 @@ static inline int may_delete(struct inod
 
 	BUG_ON(victim->d_parent->d_inode != dir);
 
+	audit_notify_watch(victim->d_inode, MAY_WRITE);
+
 	error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
 	if (error)
 		return error;
@@ -1296,6 +1302,7 @@ int vfs_create(struct inode *dir, struct
 	DQUOT_INIT(dir);
 	error = dir->i_op->create(dir, dentry, mode, nd);
 	if (!error) {
+		audit_notify_watch(dentry->d_inode, MAY_WRITE);
 		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_create(dir, dentry, mode);
 	}
@@ -1601,6 +1608,7 @@ int vfs_mknod(struct inode *dir, struct 
 	DQUOT_INIT(dir);
 	error = dir->i_op->mknod(dir, dentry, mode, dev);
 	if (!error) {
+		audit_notify_watch(dentry->d_inode, MAY_WRITE);
 		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_mknod(dir, dentry, mode, dev);
 	}
@@ -1674,6 +1682,7 @@ int vfs_mkdir(struct inode *dir, struct 
 	DQUOT_INIT(dir);
 	error = dir->i_op->mkdir(dir, dentry, mode);
 	if (!error) {
+		audit_notify_watch(dentry->d_inode, MAY_WRITE);
 		fsnotify_mkdir(dir, dentry->d_name.name);
 		security_inode_post_mkdir(dir,dentry, mode);
 	}
@@ -1915,6 +1924,7 @@ int vfs_symlink(struct inode *dir, struc
 	DQUOT_INIT(dir);
 	error = dir->i_op->symlink(dir, dentry, oldname);
 	if (!error) {
+		audit_notify_watch(dentry->d_inode, MAY_WRITE);
 		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_symlink(dir, dentry, oldname);
 	}
@@ -1988,6 +1998,7 @@ int vfs_link(struct dentry *old_dentry, 
 	error = dir->i_op->link(old_dentry, dir, new_dentry);
 	up(&old_dentry->d_inode->i_sem);
 	if (!error) {
+		audit_notify_watch(new_dentry->d_inode, MAY_WRITE);
 		fsnotify_create(dir, new_dentry->d_name.name);
 		security_inode_post_link(old_dentry, dir, new_dentry);
 	}
@@ -2111,6 +2122,7 @@ int vfs_rename_dir(struct inode *old_dir
 	}
 	if (!error) {
 		d_move(old_dentry,new_dentry);
+		audit_notify_watch(old_dentry->d_inode, MAY_WRITE);
 		security_inode_post_rename(old_dir, old_dentry,
 					   new_dir, new_dentry);
 	}
@@ -2139,6 +2151,7 @@ int vfs_rename_other(struct inode *old_d
 		/* The following d_move() should become unconditional */
 		if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
 			d_move(old_dentry, new_dentry);
+		audit_notify_watch(old_dentry->d_inode, MAY_WRITE);
 		security_inode_post_rename(old_dir, old_dentry, new_dir, new_dentry);
 	}
 	if (target)

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#1 lore raw

Hello,

In user space, the administrator refers to a file system object to be audited by its location and name. In the kernel, this reference is walked to the parent directory where the name of the file system object is put into a list called the "watchlist". Each entry in this "watchlist" refers to a "watch point" directly beneath the parent. Every object will search its parent's "watchlist" for an entry that describes a "watch point" at its location. If one is found, it will point at this entry and become "watched"[1]. "Watched" objects are auditable objects. Should the object ever leave this "watch point" it will lose this "watch".

I suspect there will be questions framed around specific parts of this design and I will address them as they come. Please keep in mind that we are not auditing based on content, but based on location and name.

[1] If a "watched" file is hard linked then the hardlink will implicitly be "watched". Should the location of the hardlink be a "watch point" itself or become a "watch point", the hardlink retains its original "watch".

-tim

fs/dcache.c +9 -0
diff -Nurp linux-2.6.12-rc2-mm1/fs/dcache.c linux-2.6.12-rc2-mm1~audit/fs/dcache.c
@@ -32,6 +32,7 @@
 #include <linux/seqlock.h>
 #include <linux/swap.h>
 #include <linux/bootmem.h>
+#include <linux/audit.h>
 
 /* #define DCACHE_DEBUG 1 */
 
@@ -97,6 +98,7 @@ static inline void dentry_iput(struct de
 {
 	struct inode *inode = dentry->d_inode;
 	if (inode) {
+		audit_attach_watch(dentry, 1);
 		dentry->d_inode = NULL;
 		list_del_init(&dentry->d_alias);
 		spin_unlock(&dentry->d_lock);
@@ -802,6 +804,7 @@ void d_instantiate(struct dentry *entry,
 	if (inode)
 		list_add(&entry->d_alias, &inode->i_dentry);
 	entry->d_inode = inode;
+	audit_attach_watch(entry, 0);
 	spin_unlock(&dcache_lock);
 	security_d_instantiate(entry, inode);
 }
@@ -978,6 +981,7 @@ struct dentry *d_splice_alias(struct ino
 		new = __d_find_alias(inode, 1);
 		if (new) {
 			BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
+			audit_attach_watch(new, 0);
 			spin_unlock(&dcache_lock);
 			security_d_instantiate(new, inode);
 			d_rehash(dentry);
@@ -987,6 +991,7 @@ struct dentry *d_splice_alias(struct ino
 			/* d_instantiate takes dcache_lock, so we do it by hand */
 			list_add(&dentry->d_alias, &inode->i_dentry);
 			dentry->d_inode = inode;
+			audit_attach_watch(dentry, 0);
 			spin_unlock(&dcache_lock);
 			security_d_instantiate(dentry, inode);
 			d_rehash(dentry);
@@ -1090,6 +1095,7 @@ struct dentry * __d_lookup(struct dentry
 		if (!d_unhashed(dentry)) {
 			atomic_inc(&dentry->d_count);
 			found = dentry;
+			audit_attach_watch(found, 0);
 		}
 		spin_unlock(&dentry->d_lock);
 		break;
@@ -1299,6 +1305,8 @@ void d_move(struct dentry * dentry, stru
 		spin_lock(&target->d_lock);
 	}
 
+	audit_attach_watch(dentry, 1);
+
 	/* Move the dentry to the target hash queue, if on different bucket */
 	if (dentry->d_flags & DCACHE_UNHASHED)
 		goto already_unhashed;
@@ -1332,6 +1340,7 @@ already_unhashed:
 		list_add(&target->d_child, &target->d_parent->d_subdirs);
 	}
 
+	audit_attach_watch(dentry, 0);
 	list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
 	spin_unlock(&target->d_lock);
 	spin_unlock(&dentry->d_lock);
fs/inode.c +5 -1
diff -Nurp linux-2.6.12-rc2-mm1/fs/inode.c linux-2.6.12-rc2-mm1~audit/fs/inode.c
@@ -22,6 +22,7 @@
 #include <linux/cdev.h>
 #include <linux/bootmem.h>
 #include <linux/inotify.h>
+#include <linux/audit.h>
 
 /*
  * This is needed for the following functions:
@@ -140,9 +141,11 @@ static struct inode *alloc_inode(struct 
 		inode->i_bdev = NULL;
 		inode->i_cdev = NULL;
 		inode->i_rdev = 0;
+		inode->i_audit = NULL;
 		inode->i_security = NULL;
 		inode->dirtied_when = 0;
-		if (security_inode_alloc(inode)) {
+		if (audit_inode_alloc(inode) || security_inode_alloc(inode)) {
+			audit_inode_free(inode);
 			if (inode->i_sb->s_op->destroy_inode)
 				inode->i_sb->s_op->destroy_inode(inode);
 			else
@@ -180,6 +183,7 @@ void destroy_inode(struct inode *inode) 
 {
 	if (inode_has_buffers(inode))
 		BUG();
+	audit_inode_free(inode);
 	security_inode_free(inode);
 	if (inode->i_sb->s_op->destroy_inode)
 		inode->i_sb->s_op->destroy_inode(inode);
fs/namei.c +13 -0
diff -Nurp linux-2.6.12-rc2-mm1/fs/namei.c linux-2.6.12-rc2-mm1~audit/fs/namei.c
@@ -225,6 +225,8 @@ int permission(struct inode *inode, int 
 {
 	int retval, submask;
 
+	audit_notify_watch(inode, mask);
+
 	if (mask & MAY_WRITE) {
 		umode_t mode = inode->i_mode;
 
@@ -358,6 +360,8 @@ static inline int exec_permission_lite(s
 	if (inode->i_op && inode->i_op->permission)
 		return -EAGAIN;
 
+	audit_notify_watch(inode, MAY_EXEC);
+
 	if (current->fsuid == inode->i_uid)
 		mode >>= 6;
 	else if (in_group_p(inode->i_gid))
@@ -1172,6 +1176,8 @@ static inline int may_delete(struct inod
 
 	BUG_ON(victim->d_parent->d_inode != dir);
 
+	audit_notify_watch(victim->d_inode, MAY_WRITE);
+
 	error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
 	if (error)
 		return error;
@@ -1296,6 +1302,7 @@ int vfs_create(struct inode *dir, struct
 	DQUOT_INIT(dir);
 	error = dir->i_op->create(dir, dentry, mode, nd);
 	if (!error) {
+		audit_notify_watch(dentry->d_inode, MAY_WRITE);
 		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_create(dir, dentry, mode);
 	}
@@ -1601,6 +1608,7 @@ int vfs_mknod(struct inode *dir, struct 
 	DQUOT_INIT(dir);
 	error = dir->i_op->mknod(dir, dentry, mode, dev);
 	if (!error) {
+		audit_notify_watch(dentry->d_inode, MAY_WRITE);
 		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_mknod(dir, dentry, mode, dev);
 	}
@@ -1674,6 +1682,7 @@ int vfs_mkdir(struct inode *dir, struct 
 	DQUOT_INIT(dir);
 	error = dir->i_op->mkdir(dir, dentry, mode);
 	if (!error) {
+		audit_notify_watch(dentry->d_inode, MAY_WRITE);
 		fsnotify_mkdir(dir, dentry->d_name.name);
 		security_inode_post_mkdir(dir,dentry, mode);
 	}
@@ -1915,6 +1924,7 @@ int vfs_symlink(struct inode *dir, struc
 	DQUOT_INIT(dir);
 	error = dir->i_op->symlink(dir, dentry, oldname);
 	if (!error) {
+		audit_notify_watch(dentry->d_inode, MAY_WRITE);
 		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_symlink(dir, dentry, oldname);
 	}
@@ -1988,6 +1998,7 @@ int vfs_link(struct dentry *old_dentry, 
 	error = dir->i_op->link(old_dentry, dir, new_dentry);
 	up(&old_dentry->d_inode->i_sem);
 	if (!error) {
+		audit_notify_watch(new_dentry->d_inode, MAY_WRITE);
 		fsnotify_create(dir, new_dentry->d_name.name);
 		security_inode_post_link(old_dentry, dir, new_dentry);
 	}
@@ -2111,6 +2122,7 @@ int vfs_rename_dir(struct inode *old_dir
 	}
 	if (!error) {
 		d_move(old_dentry,new_dentry);
+		audit_notify_watch(old_dentry->d_inode, MAY_WRITE);
 		security_inode_post_rename(old_dir, old_dentry,
 					   new_dir, new_dentry);
 	}
@@ -2139,6 +2151,7 @@ int vfs_rename_other(struct inode *old_d
 		/* The following d_move() should become unconditional */
 		if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
 			d_move(old_dentry, new_dentry);
+		audit_notify_watch(old_dentry->d_inode, MAY_WRITE);
 		security_inode_post_rename(old_dir, old_dentry, new_dir, new_dentry);
 	}
 	if (target)
include/linux/audit.h +63 -8

107 lines not on this page · raw message

include/linux/fs.h +2 -0
diff -Nurp linux-2.6.12-rc2-mm1/include/linux/fs.h linux-2.6.12-rc2-mm1~audit/include/linux/fs.h
@@ -214,6 +214,7 @@ extern int dir_notify_enable;
 #include <linux/prio_tree.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/audit.h>
 
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
@@ -477,6 +478,7 @@ struct inode {
 	struct semaphore	inotify_sem;	/* protects the watches list */
 #endif
 
+	struct audit_data	*i_audit;
 	unsigned long		i_state;
 	unsigned long		dirtied_when;	/* jiffies of first dirtying */
 
init/Kconfig +10 -0
diff -Nurp linux-2.6.12-rc2-mm1/init/Kconfig linux-2.6.12-rc2-mm1~audit/init/Kconfig
@@ -198,6 +198,16 @@ config AUDITSYSCALL
 	  can be used independently or with another kernel subsystem,
 	  such as SELinux.
 
+config AUDITFILESYSTEM
+	bool "Enable file system auditing support"
+	depends on AUDITSYSCALL
+	default n
+	help
+	  Enable file system auditing for regular files and directories.
+	  When a targeted file or directory is accessed, an audit record
+	  is generated describing the inode accessed, how it was accessed,
+	  and by whom (ie: pid and system call).
+
 config HOTPLUG
 	bool "Support for hot-pluggable devices" if !ARCH_S390
 	default ARCH_S390
kernel/Makefile +1 -0
diff -Nurp linux-2.6.12-rc2-mm1/kernel/Makefile linux-2.6.12-rc2-mm1~audit/kernel/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_IKCONFIG_PROC) += configs.o
 obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
 obj-$(CONFIG_AUDIT) += audit.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
+obj-$(CONFIG_AUDITFILESYSTEM) += auditfs.o
 obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
kernel/audit.c +17 -0
diff -Nurp linux-2.6.12-rc2-mm1/kernel/audit.c linux-2.6.12-rc2-mm1~audit/kernel/audit.c
@@ -322,6 +322,9 @@ static int audit_netlink_ok(kernel_cap_t
 	case AUDIT_SET:
 	case AUDIT_ADD:
 	case AUDIT_DEL:
+	case AUDIT_WATCH_INS:
+	case AUDIT_WATCH_REM:
+	case AUDIT_WATCH_LIST:
 		if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
 			err = -EPERM;
 		break;
@@ -416,6 +419,19 @@ static int audit_receive_msg(struct sk_b
 		err = -EOPNOTSUPP;
 #endif
 		break;
+	case AUDIT_WATCH_INS:
+	case AUDIT_WATCH_REM:
+		if (nlh->nlmsg_len < sizeof(struct audit_watch))
+			return -EINVAL;
+		err = audit_receive_watch(nlh->nlmsg_type,
+					  NETLINK_CB(skb).pid,
+					  uid, seq, data);
+		break;
+	case AUDIT_WATCH_LIST:
+		err = audit_list_watches(nlh->nlmsg_type,
+					 NETLINK_CB(skb).pid,
+					 uid, seq, data);
+		break;
 	default:
 		err = -EINVAL;
 		break;
@@ -560,6 +576,7 @@ static int __init audit_init(void)
 
 	audit_initialized = 1;
 	audit_enabled = audit_default;
+	audit_filesystem_init();
 	audit_log(NULL, "initialized");
 	return 0;
 }
kernel/auditfs.c +511 -0

511 lines not on this page · raw message

kernel/auditsc.c +78 -0

99 lines not on this page · raw message

security/selinux/nlmsgtab.c +2 -0
diff -Nurp linux-2.6.12-rc2-mm1/security/selinux/nlmsgtab.c linux-2.6.12-rc2-mm1~audit/security/selinux/nlmsgtab.c
@@ -98,6 +98,8 @@ static struct nlmsg_perm nlmsg_audit_per
 	{ AUDIT_DEL,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
 	{ AUDIT_USER,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
 	{ AUDIT_LOGIN,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
+	{ AUDIT_WATCH_INS,	NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
+	{ AUDIT_WATCH_REM,	NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
 };
 
 
#3 lore raw
In reply to a message not in the archive
Quoted 13 lines · you

security/selinux/nlmsgtab.c static struct nlmsg_perm nlmsg_audit_per · line 103

Quoted 11 lines · Timothy R. Chavez

--- linux-2.6.12-rc2-mm1/security/selinux/nlmsgtab.c 2005-03-02
01:38:19.000000000 -0600 +++
linux-2.6.12-rc2-mm1~audit/security/selinux/nlmsgtab.c 2005-04-05
13:16:26.000000000 -0500 @@ -98,6 +98,8 @@ static struct nlmsg_perm nlmsg_audit_per

        { AUDIT_DEL,            NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
        { AUDIT_USER,           NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
        { AUDIT_LOGIN,          NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
security/selinux/nlmsgtab.c +2 -0
+       { AUDIT_WATCH_INS,      NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
+       { AUDIT_WATCH_REM,      NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
 };
Quoted 1 line

Do you not need to add AUDIT_WATCH_LIST to this?

Oh yes, that's right. I'm not sure its pertinent ATM. The feature isn't supported in the downloadable version of the user space tools yet. But regardless, it should be added. Thanks David.

-tim