[PATCH] audit signal recipients
When auditing syscalls that send signals, log the pid and security context for each target process. Optimize the data collection by adding a counter for signal-related rules, and avoiding allocating an aux struct unless we have more than one target process. For process groups, collect pid/context data in blocks of 16. Move the audit_signal_info() hook up in check_kill_permission() so we audit attempts where permission is denied. Signed-off-by: Amy Griffis <amy.griffis@hp.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
+47
-1
@@ -311,6 +311,43 @@ int audit_match_class(int class, unsigned syscall)
|
||||
return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall);
|
||||
}
|
||||
|
||||
static inline int audit_match_class_bits(int class, u32 *mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (classes[class]) {
|
||||
for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
|
||||
if (mask[i] & classes[class][i])
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int audit_match_signal(struct audit_entry *entry)
|
||||
{
|
||||
struct audit_field *arch = entry->rule.arch_f;
|
||||
|
||||
if (!arch) {
|
||||
/* When arch is unspecified, we must check both masks on biarch
|
||||
* as syscall number alone is ambiguous. */
|
||||
return (audit_match_class_bits(AUDIT_CLASS_SIGNAL,
|
||||
entry->rule.mask) &&
|
||||
audit_match_class_bits(AUDIT_CLASS_SIGNAL_32,
|
||||
entry->rule.mask));
|
||||
}
|
||||
|
||||
switch(audit_classify_arch(arch->val)) {
|
||||
case 0: /* native */
|
||||
return (audit_match_class_bits(AUDIT_CLASS_SIGNAL,
|
||||
entry->rule.mask));
|
||||
case 1: /* 32bit on biarch */
|
||||
return (audit_match_class_bits(AUDIT_CLASS_SIGNAL_32,
|
||||
entry->rule.mask));
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Common user-space to kernel rule translation. */
|
||||
static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
|
||||
{
|
||||
@@ -429,6 +466,7 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
|
||||
err = -EINVAL;
|
||||
goto exit_free;
|
||||
}
|
||||
entry->rule.arch_f = f;
|
||||
break;
|
||||
case AUDIT_PERM:
|
||||
if (f->val & ~15)
|
||||
@@ -519,7 +557,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
||||
case AUDIT_FSGID:
|
||||
case AUDIT_LOGINUID:
|
||||
case AUDIT_PERS:
|
||||
case AUDIT_ARCH:
|
||||
case AUDIT_MSGTYPE:
|
||||
case AUDIT_PPID:
|
||||
case AUDIT_DEVMAJOR:
|
||||
@@ -531,6 +568,9 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
||||
case AUDIT_ARG2:
|
||||
case AUDIT_ARG3:
|
||||
break;
|
||||
case AUDIT_ARCH:
|
||||
entry->rule.arch_f = f;
|
||||
break;
|
||||
case AUDIT_SUBJ_USER:
|
||||
case AUDIT_SUBJ_ROLE:
|
||||
case AUDIT_SUBJ_TYPE:
|
||||
@@ -1221,6 +1261,9 @@ static inline int audit_add_rule(struct audit_entry *entry,
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
if (!dont_count)
|
||||
audit_n_rules++;
|
||||
|
||||
if (!audit_match_signal(entry))
|
||||
audit_signals++;
|
||||
#endif
|
||||
mutex_unlock(&audit_filter_mutex);
|
||||
|
||||
@@ -1294,6 +1337,9 @@ static inline int audit_del_rule(struct audit_entry *entry,
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
if (!dont_count)
|
||||
audit_n_rules--;
|
||||
|
||||
if (!audit_match_signal(entry))
|
||||
audit_signals--;
|
||||
#endif
|
||||
mutex_unlock(&audit_filter_mutex);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user