audit/stable-4.15 PR 20171113
-----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEEcQCq365ubpQNLgrWVeRaWujKfIoFAloJ+P8UHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQVeRaWujKfIqbhg//S7a4vVnOz9ttK3lR+w4rXHQnsH4a h+8X9+FYwtcfXNqfki/MGbmOerh1pqJZstWGVJ1kVizJxjPGsF8ZzcaBXFmlfflu E6kX17L9n//1A0VZTYKCqqqh4rRPFqNdF0NDySO6p0I6PRZ1xHBWw6f1aIGabDru ZpwWkiF/PliP3/vEPJkux84ovwc0+vg8DNhwtlN5StT6ty5YhM8KMuYCnaGtdbvC qBZYWNxOSxdf6Lw7Yq7yeziLa7+yvgUbGCrZDF40T/WDLl/CZILX5KuVkDlgKFl2 wgZz5cesAEKFLalEZ3w2EAhZ7a941BWwkbcR0NJiCznTnUUAOD2EZVpapnSqb5/5 XcOGWKetx2BZvpj1hZ8KJa9Nd4Qr/w0iZoreUDnGeItAepNXLQ3Cu0wTdjPGybn5 N8EtL0FSlnUe6FAva+HXNXmrt9fDo9Vj4X3b32un1c0JiFULCBAb6QO83UG/FCzv svFjIG4HnrjnEHa3B4pxN083ljSZGJttCjnjErEM0oGDmUCfQ8b9WGvkTJEQpPA6 wEAZWPL5MwwWhwZM+qiq+vFTVNLKFXFZO1aPerw8InANoMIqqkC4M4zaOSW2yZd9 ixrATqmikuBK2mG9msG3lOB+XEs6Yz0qF10VQP0NzdeSKVmoZQROQS9Y1nacmKOC jWgvyVPQ9jajByM= =SKna -----END PGP SIGNATURE----- Merge tag 'audit-pr-20171113' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit Pull audit updates from Paul Moore: "Another relatively small pull request for audit, nine patches total. The only real new bit of functionality is the patch from Richard which adds the ability to filter records based on the filesystem type. The remainder are bug fixes and cleanups; the bug fix highlights include: - ensuring that we properly audit init/PID-1 (me) - allowing the audit daemon to shutdown the kernel/auditd connection cleanly by setting the audit PID to zero (Steve)" * tag 'audit-pr-20171113' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: audit: filter PATH records keyed on filesystem magic Audit: remove unused audit_log_secctx function audit: Allow auditd to set pid to 0 to end auditing audit: Add new syscalls to the perm=w filter audit: use audit_set_enabled() in audit_enable() audit: convert audit_ever_enabled to a boolean audit: don't use simple_strtol() anymore audit: initialize the audit subsystem as early as possible audit: ensure that 'audit=1' actually enables audit for PID 1
This commit is contained in:
commit
f9bab2677a
|
@ -31,3 +31,6 @@ __NR_renameat,
|
|||
__NR_linkat,
|
||||
__NR_symlinkat,
|
||||
#endif
|
||||
#ifdef __NR_renameat2
|
||||
__NR_renameat2,
|
||||
#endif
|
||||
|
|
|
@ -20,3 +20,6 @@ __NR_ftruncate64,
|
|||
#ifdef __NR_bind
|
||||
__NR_bind, /* bind can affect fs object only in one way... */
|
||||
#endif
|
||||
#ifdef __NR_fallocate
|
||||
__NR_fallocate,
|
||||
#endif
|
||||
|
|
|
@ -149,12 +149,6 @@ extern void audit_log_key(struct audit_buffer *ab,
|
|||
extern void audit_log_link_denied(const char *operation,
|
||||
const struct path *link);
|
||||
extern void audit_log_lost(const char *message);
|
||||
#ifdef CONFIG_SECURITY
|
||||
extern void audit_log_secctx(struct audit_buffer *ab, u32 secid);
|
||||
#else
|
||||
static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
extern int audit_log_task_context(struct audit_buffer *ab);
|
||||
extern void audit_log_task_info(struct audit_buffer *ab,
|
||||
|
@ -203,8 +197,6 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
|
|||
static inline void audit_log_link_denied(const char *string,
|
||||
const struct path *link)
|
||||
{ }
|
||||
static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
|
||||
{ }
|
||||
static inline int audit_log_task_context(struct audit_buffer *ab)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -157,8 +157,9 @@
|
|||
#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */
|
||||
#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */
|
||||
#define AUDIT_FILTER_TYPE 0x05 /* Apply rule at audit_log_start */
|
||||
#define AUDIT_FILTER_FS 0x06 /* Apply rule at __audit_inode_child */
|
||||
|
||||
#define AUDIT_NR_FILTERS 6
|
||||
#define AUDIT_NR_FILTERS 7
|
||||
|
||||
#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */
|
||||
|
||||
|
@ -258,6 +259,7 @@
|
|||
#define AUDIT_OBJ_LEV_HIGH 23
|
||||
#define AUDIT_LOGINUID_SET 24
|
||||
#define AUDIT_SESSIONID 25 /* Session ID */
|
||||
#define AUDIT_FSTYPE 26 /* FileSystem Type */
|
||||
|
||||
/* These are ONLY useful when checking
|
||||
* at syscall exit time (AUDIT_AT_EXIT). */
|
||||
|
@ -337,13 +339,15 @@ enum {
|
|||
#define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008
|
||||
#define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010
|
||||
#define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020
|
||||
#define AUDIT_FEATURE_BITMAP_FILTER_FS 0x00000040
|
||||
|
||||
#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \
|
||||
AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \
|
||||
AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | \
|
||||
AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \
|
||||
AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \
|
||||
AUDIT_FEATURE_BITMAP_LOST_RESET)
|
||||
AUDIT_FEATURE_BITMAP_LOST_RESET | \
|
||||
AUDIT_FEATURE_BITMAP_FILTER_FS)
|
||||
|
||||
/* deprecated: AUDIT_VERSION_* */
|
||||
#define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL
|
||||
|
|
|
@ -85,13 +85,13 @@ static int audit_initialized;
|
|||
#define AUDIT_OFF 0
|
||||
#define AUDIT_ON 1
|
||||
#define AUDIT_LOCKED 2
|
||||
u32 audit_enabled;
|
||||
u32 audit_ever_enabled;
|
||||
u32 audit_enabled = AUDIT_OFF;
|
||||
bool audit_ever_enabled = !!AUDIT_OFF;
|
||||
|
||||
EXPORT_SYMBOL_GPL(audit_enabled);
|
||||
|
||||
/* Default state when kernel boots without any parameters. */
|
||||
static u32 audit_default;
|
||||
static u32 audit_default = AUDIT_OFF;
|
||||
|
||||
/* If auditing cannot proceed, audit_failure selects what happens. */
|
||||
static u32 audit_failure = AUDIT_FAIL_PRINTK;
|
||||
|
@ -1197,25 +1197,28 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
pid_t auditd_pid;
|
||||
struct pid *req_pid = task_tgid(current);
|
||||
|
||||
/* sanity check - PID values must match */
|
||||
if (new_pid != pid_vnr(req_pid))
|
||||
/* Sanity check - PID values must match. Setting
|
||||
* pid to 0 is how auditd ends auditing. */
|
||||
if (new_pid && (new_pid != pid_vnr(req_pid)))
|
||||
return -EINVAL;
|
||||
|
||||
/* test the auditd connection */
|
||||
audit_replace(req_pid);
|
||||
|
||||
auditd_pid = auditd_pid_vnr();
|
||||
/* only the current auditd can unregister itself */
|
||||
if ((!new_pid) && (new_pid != auditd_pid)) {
|
||||
audit_log_config_change("audit_pid", new_pid,
|
||||
auditd_pid, 0);
|
||||
return -EACCES;
|
||||
}
|
||||
/* replacing a healthy auditd is not allowed */
|
||||
if (auditd_pid && new_pid) {
|
||||
audit_log_config_change("audit_pid", new_pid,
|
||||
auditd_pid, 0);
|
||||
return -EEXIST;
|
||||
if (auditd_pid) {
|
||||
/* replacing a healthy auditd is not allowed */
|
||||
if (new_pid) {
|
||||
audit_log_config_change("audit_pid",
|
||||
new_pid, auditd_pid, 0);
|
||||
return -EEXIST;
|
||||
}
|
||||
/* only current auditd can unregister itself */
|
||||
if (pid_vnr(req_pid) != auditd_pid) {
|
||||
audit_log_config_change("audit_pid",
|
||||
new_pid, auditd_pid, 0);
|
||||
return -EACCES;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_pid) {
|
||||
|
@ -1549,8 +1552,6 @@ static int __init audit_init(void)
|
|||
register_pernet_subsys(&audit_net_ops);
|
||||
|
||||
audit_initialized = AUDIT_INITIALIZED;
|
||||
audit_enabled = audit_default;
|
||||
audit_ever_enabled |= !!audit_default;
|
||||
|
||||
kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
|
||||
if (IS_ERR(kauditd_task)) {
|
||||
|
@ -1564,14 +1565,21 @@ static int __init audit_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
__initcall(audit_init);
|
||||
postcore_initcall(audit_init);
|
||||
|
||||
/* Process kernel command-line parameter at boot time. audit=0 or audit=1. */
|
||||
static int __init audit_enable(char *str)
|
||||
{
|
||||
audit_default = !!simple_strtol(str, NULL, 0);
|
||||
if (!audit_default)
|
||||
long val;
|
||||
|
||||
if (kstrtol(str, 0, &val))
|
||||
panic("audit: invalid 'audit' parameter value (%s)\n", str);
|
||||
audit_default = (val ? AUDIT_ON : AUDIT_OFF);
|
||||
|
||||
if (audit_default == AUDIT_OFF)
|
||||
audit_initialized = AUDIT_DISABLED;
|
||||
if (audit_set_enabled(audit_default))
|
||||
panic("audit: error setting audit state (%d)\n", audit_default);
|
||||
|
||||
pr_info("%s\n", audit_default ?
|
||||
"enabled (after initialization)" : "disabled (until reboot)");
|
||||
|
@ -2337,32 +2345,6 @@ void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURITY
|
||||
/**
|
||||
* audit_log_secctx - Converts and logs SELinux context
|
||||
* @ab: audit_buffer
|
||||
* @secid: security number
|
||||
*
|
||||
* This is a helper function that calls security_secid_to_secctx to convert
|
||||
* secid to secctx and then adds the (converted) SELinux context to the audit
|
||||
* log by calling audit_log_format, thus also preventing leak of internal secid
|
||||
* to userspace. If secid cannot be converted audit_panic is called.
|
||||
*/
|
||||
void audit_log_secctx(struct audit_buffer *ab, u32 secid)
|
||||
{
|
||||
u32 len;
|
||||
char *secctx;
|
||||
|
||||
if (security_secid_to_secctx(secid, &secctx, &len)) {
|
||||
audit_panic("Cannot convert secid to context");
|
||||
} else {
|
||||
audit_log_format(ab, " obj=%s", secctx);
|
||||
security_release_secctx(secctx, len);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(audit_log_secctx);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(audit_log_start);
|
||||
EXPORT_SYMBOL(audit_log_end);
|
||||
EXPORT_SYMBOL(audit_log_format);
|
||||
|
|
|
@ -208,7 +208,7 @@ struct audit_context {
|
|||
struct audit_proctitle proctitle;
|
||||
};
|
||||
|
||||
extern u32 audit_ever_enabled;
|
||||
extern bool audit_ever_enabled;
|
||||
|
||||
extern void audit_copy_inode(struct audit_names *name,
|
||||
const struct dentry *dentry,
|
||||
|
|
|
@ -56,7 +56,8 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
|
|||
LIST_HEAD_INIT(audit_filter_list[3]),
|
||||
LIST_HEAD_INIT(audit_filter_list[4]),
|
||||
LIST_HEAD_INIT(audit_filter_list[5]),
|
||||
#if AUDIT_NR_FILTERS != 6
|
||||
LIST_HEAD_INIT(audit_filter_list[6]),
|
||||
#if AUDIT_NR_FILTERS != 7
|
||||
#error Fix audit_filter_list initialiser
|
||||
#endif
|
||||
};
|
||||
|
@ -67,6 +68,7 @@ static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {
|
|||
LIST_HEAD_INIT(audit_rules_list[3]),
|
||||
LIST_HEAD_INIT(audit_rules_list[4]),
|
||||
LIST_HEAD_INIT(audit_rules_list[5]),
|
||||
LIST_HEAD_INIT(audit_rules_list[6]),
|
||||
};
|
||||
|
||||
DEFINE_MUTEX(audit_filter_mutex);
|
||||
|
@ -263,6 +265,7 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule_data *
|
|||
#endif
|
||||
case AUDIT_FILTER_USER:
|
||||
case AUDIT_FILTER_TYPE:
|
||||
case AUDIT_FILTER_FS:
|
||||
;
|
||||
}
|
||||
if (unlikely(rule->action == AUDIT_POSSIBLE)) {
|
||||
|
@ -338,6 +341,21 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
|
|||
entry->rule.listnr != AUDIT_FILTER_USER)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case AUDIT_FSTYPE:
|
||||
if (entry->rule.listnr != AUDIT_FILTER_FS)
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(entry->rule.listnr) {
|
||||
case AUDIT_FILTER_FS:
|
||||
switch(f->type) {
|
||||
case AUDIT_FSTYPE:
|
||||
case AUDIT_FILTERKEY:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
switch(f->type) {
|
||||
|
@ -391,6 +409,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
|
|||
return -EINVAL;
|
||||
/* FALL THROUGH */
|
||||
case AUDIT_ARCH:
|
||||
case AUDIT_FSTYPE:
|
||||
if (f->op != Audit_not_equal && f->op != Audit_equal)
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
@ -910,10 +929,13 @@ static inline int audit_add_rule(struct audit_entry *entry)
|
|||
#ifdef CONFIG_AUDITSYSCALL
|
||||
int dont_count = 0;
|
||||
|
||||
/* If either of these, don't count towards total */
|
||||
if (entry->rule.listnr == AUDIT_FILTER_USER ||
|
||||
entry->rule.listnr == AUDIT_FILTER_TYPE)
|
||||
/* If any of these, don't count towards total */
|
||||
switch(entry->rule.listnr) {
|
||||
case AUDIT_FILTER_USER:
|
||||
case AUDIT_FILTER_TYPE:
|
||||
case AUDIT_FILTER_FS:
|
||||
dont_count = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
mutex_lock(&audit_filter_mutex);
|
||||
|
@ -989,10 +1011,13 @@ int audit_del_rule(struct audit_entry *entry)
|
|||
#ifdef CONFIG_AUDITSYSCALL
|
||||
int dont_count = 0;
|
||||
|
||||
/* If either of these, don't count towards total */
|
||||
if (entry->rule.listnr == AUDIT_FILTER_USER ||
|
||||
entry->rule.listnr == AUDIT_FILTER_TYPE)
|
||||
/* If any of these, don't count towards total */
|
||||
switch(entry->rule.listnr) {
|
||||
case AUDIT_FILTER_USER:
|
||||
case AUDIT_FILTER_TYPE:
|
||||
case AUDIT_FILTER_FS:
|
||||
dont_count = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
mutex_lock(&audit_filter_mutex);
|
||||
|
|
|
@ -1869,10 +1869,33 @@ void __audit_inode_child(struct inode *parent,
|
|||
struct inode *inode = d_backing_inode(dentry);
|
||||
const char *dname = dentry->d_name.name;
|
||||
struct audit_names *n, *found_parent = NULL, *found_child = NULL;
|
||||
struct audit_entry *e;
|
||||
struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS];
|
||||
int i;
|
||||
|
||||
if (!context->in_syscall)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
if (!list_empty(list)) {
|
||||
list_for_each_entry_rcu(e, list, list) {
|
||||
for (i = 0; i < e->rule.field_count; i++) {
|
||||
struct audit_field *f = &e->rule.fields[i];
|
||||
|
||||
if (f->type == AUDIT_FSTYPE) {
|
||||
if (audit_comparator(parent->i_sb->s_magic,
|
||||
f->op, f->val)) {
|
||||
if (e->rule.action == AUDIT_NEVER) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (inode)
|
||||
handle_one(inode);
|
||||
|
||||
|
|
Loading…
Reference in New Issue