Skip to content
Snippets Groups Projects
  • Steve Grubb's avatar
    d96fcfd5
    audit: CONFIG_CHANGE don't log internal bookkeeping as an event · d96fcfd5
    Steve Grubb authored
    
    [ Upstream commit 70b3eeed ]
    
    Common Criteria calls out for any action that modifies the audit trail to
    be recorded. That usually is interpreted to mean insertion or removal of
    rules. It is not required to log modification of the inode information
    since the watch is still in effect. Additionally, if the rule is a never
    rule and the underlying file is one they do not want events for, they
    get an event for this bookkeeping update against their wishes.
    
    Since no device/inode info is logged at insertion and no device/inode
    information is logged on update, there is nothing meaningful being
    communicated to the admin by the CONFIG_CHANGE updated_rules event. One
    can assume that the rule was not "modified" because it is still watching
    the intended target. If the device or inode cannot be resolved, then
    audit_panic is called which is sufficient.
    
    The correct resolution is to drop logging config_update events since
    the watch is still in effect but just on another unknown inode.
    
    Signed-off-by: default avatarSteve Grubb <sgrubb@redhat.com>
    Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    d96fcfd5
    History
    audit: CONFIG_CHANGE don't log internal bookkeeping as an event
    Steve Grubb authored
    
    [ Upstream commit 70b3eeed ]
    
    Common Criteria calls out for any action that modifies the audit trail to
    be recorded. That usually is interpreted to mean insertion or removal of
    rules. It is not required to log modification of the inode information
    since the watch is still in effect. Additionally, if the rule is a never
    rule and the underlying file is one they do not want events for, they
    get an event for this bookkeeping update against their wishes.
    
    Since no device/inode info is logged at insertion and no device/inode
    information is logged on update, there is nothing meaningful being
    communicated to the admin by the CONFIG_CHANGE updated_rules event. One
    can assume that the rule was not "modified" because it is still watching
    the intended target. If the device or inode cannot be resolved, then
    audit_panic is called which is sufficient.
    
    The correct resolution is to drop logging config_update events since
    the watch is still in effect but just on another unknown inode.
    
    Signed-off-by: default avatarSteve Grubb <sgrubb@redhat.com>
    Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
audit_watch.c 14.03 KiB
// SPDX-License-Identifier: GPL-2.0-or-later
/* audit_watch.c -- watching inodes
 *
 * Copyright 2003-2009 Red Hat, Inc.
 * Copyright 2005 Hewlett-Packard Development Company, L.P.
 * Copyright 2005 IBM Corporation
 */

#include <linux/file.h>
#include <linux/kernel.h>
#include <linux/audit.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/fs.h>
#include <linux/fsnotify_backend.h>
#include <linux/namei.h>
#include <linux/netlink.h>
#include <linux/refcount.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/security.h>
#include "audit.h"

/*
 * Reference counting:
 *
 * audit_parent: lifetime is from audit_init_parent() to receipt of an FS_IGNORED
 * 	event.  Each audit_watch holds a reference to its associated parent.
 *
 * audit_watch: if added to lists, lifetime is from audit_init_watch() to
 * 	audit_remove_watch().  Additionally, an audit_watch may exist
 * 	temporarily to assist in searching existing filter data.  Each
 * 	audit_krule holds a reference to its associated watch.
 */

struct audit_watch {
	refcount_t		count;	/* reference count */
	dev_t			dev;	/* associated superblock device */
	char			*path;	/* insertion path */
	unsigned long		ino;	/* associated inode number */
	struct audit_parent	*parent; /* associated parent */
	struct list_head	wlist;	/* entry in parent->watches list */
	struct list_head	rules;	/* anchor for krule->rlist */
};

struct audit_parent {
	struct list_head	watches; /* anchor for audit_watch->wlist */
	struct fsnotify_mark mark; /* fsnotify mark on the inode */
};

/* fsnotify handle. */
static struct fsnotify_group *audit_watch_group;

/* fsnotify events we care about. */
#define AUDIT_FS_WATCH (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\
			FS_MOVE_SELF | FS_EVENT_ON_CHILD | FS_UNMOUNT)

static void audit_free_parent(struct audit_parent *parent)
{
	WARN_ON(!list_empty(&parent->watches));
	kfree(parent);
}

static void audit_watch_free_mark(struct fsnotify_mark *entry)
{
	struct audit_parent *parent;

	parent = container_of(entry, struct audit_parent, mark);
	audit_free_parent(parent);
}