X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=kernel%2Fauditfilter.c;h=74cc0fc6bb8169894cd7820f3877432796a7e628;hb=6ddcd3b0201a7ad72294347636d2b4028ddbd95d;hp=3749193aed8cf805a5c96fea00331379735c45ea;hpb=a22a0fab32e1216df56e4b9a577dc5c922cf7524;p=powerpc.git diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 3749193aed..74cc0fc6bb 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -311,6 +311,45 @@ int audit_match_class(int class, unsigned syscall) return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall); } +#ifdef CONFIG_AUDITSYSCALL +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; + } +} +#endif + /* Common user-space to kernel rule translation. */ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) { @@ -429,6 +468,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 +559,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 +570,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 +1263,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 +1339,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);