add SIGNAL syscall class (v2)
Subsystems (5)
PATCH 1/2 add SIGNAL syscall class (v2)
[[ Re-post adding some missing arch bitmaps ]]
Add a syscall class for sending signals.
--- arch/ia64/ia32/audit.c | 5 +++++ arch/ia64/kernel/audit.c | 8 ++++++++ arch/powerpc/kernel/audit.c | 8 ++++++++ arch/powerpc/kernel/compat_audit.c | 5 +++++ arch/s390/kernel/audit.c | 8 ++++++++ arch/s390/kernel/compat_audit.c | 5 +++++ arch/sparc64/kernel/audit.c | 8 ++++++++ arch/sparc64/kernel/compat_audit.c | 5 +++++ arch/x86_64/ia32/audit.c | 5 +++++ arch/x86_64/kernel/audit.c | 8 ++++++++ include/asm-generic/audit_signal.h | 3 +++ include/linux/audit.h | 2 ++ lib/audit.c | 6 ++++++ 13 files changed, 76 insertions(+), 0 deletions(-)
arch/ia64/ia32/audit.c +5 -0
@@ -20,6 +20,11 @@ unsigned ia32_read_class[] = { ~0U }; +unsigned ia32_signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int ia32_classify_syscall (unsigned syscall) {switch (syscall) {
arch/ia64/kernel/audit.c +8 -0
@@ -23,6 +23,11 @@ static unsigned chattr_class[] = { ~0U }; +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_IA32_SUPPORT
@@ -49,15 +54,18 @@ static int __init audit_classes_init(void)extern __u32 ia32_write_class[];extern __u32 ia32_read_class[];extern __u32 ia32_chattr_class[]; +extern __u32 ia32_signal_class[];audit_register_class (AUDIT_CLASS_WRITE_32 , ia32_write_class);audit_register_class (AUDIT_CLASS_READ_32 , ia32_read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE_32 , ia32_dir_class);audit_register_class (AUDIT_CLASS_CHATTR_32 , ia32_chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL_32 , ia32_signal_class);#endif audit_register_class (AUDIT_CLASS_WRITE , write_class);audit_register_class (AUDIT_CLASS_READ , read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class);audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL , signal_class);return 0 ; }
arch/powerpc/kernel/audit.c +8 -0
@@ -23,6 +23,11 @@ static unsigned chattr_class[] = { ~0U }; +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_PPC64
@@ -51,15 +56,18 @@ static int __init audit_classes_init(void)extern __u32 ppc32_write_class[];extern __u32 ppc32_read_class[];extern __u32 ppc32_chattr_class[]; +extern __u32 ppc32_signal_class[];audit_register_class (AUDIT_CLASS_WRITE_32 , ppc32_write_class);audit_register_class (AUDIT_CLASS_READ_32 , ppc32_read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE_32 , ppc32_dir_class);audit_register_class (AUDIT_CLASS_CHATTR_32 , ppc32_chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL_32 , ppc32_signal_class);#endif audit_register_class (AUDIT_CLASS_WRITE , write_class);audit_register_class (AUDIT_CLASS_READ , read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class);audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL , signal_class);return 0 ; }
arch/powerpc/kernel/compat_audit.c +5 -0
@@ -21,6 +21,11 @@ unsigned ppc32_read_class[] = { ~0U }; +unsigned ppc32_signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int ppc32_classify_syscall (unsigned syscall) {switch (syscall) {
arch/s390/kernel/audit.c +8 -0
@@ -23,6 +23,11 @@ static unsigned chattr_class[] = { ~0U }; +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_COMPAT
@@ -51,15 +56,18 @@ static int __init audit_classes_init(void)extern __u32 s390_write_class[];extern __u32 s390_read_class[];extern __u32 s390_chattr_class[]; +extern __u32 s390_signal_class[];audit_register_class (AUDIT_CLASS_WRITE_32 , s390_write_class);audit_register_class (AUDIT_CLASS_READ_32 , s390_read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE_32 , s390_dir_class);audit_register_class (AUDIT_CLASS_CHATTR_32 , s390_chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL_32 , s390_signal_class);#endif audit_register_class (AUDIT_CLASS_WRITE , write_class);audit_register_class (AUDIT_CLASS_READ , read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class);audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL , signal_class);return 0 ; }
arch/s390/kernel/compat_audit.c +5 -0
@@ -21,6 +21,11 @@ unsigned s390_read_class[] = { ~0U }; +unsigned s390_signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int s390_classify_syscall (unsigned syscall) {switch (syscall) {
arch/sparc64/kernel/audit.c +8 -0
@@ -23,6 +23,11 @@ static unsigned chattr_class[] = { ~0U }; +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_SPARC32_COMPAT
@@ -51,15 +56,18 @@ static int __init audit_classes_init(void)extern __u32 sparc32_write_class[];extern __u32 sparc32_read_class[];extern __u32 sparc32_chattr_class[]; +extern __u32 sparc32_signal_class[];audit_register_class (AUDIT_CLASS_WRITE_32 , sparc32_write_class);audit_register_class (AUDIT_CLASS_READ_32 , sparc32_read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE_32 , sparc32_dir_class);audit_register_class (AUDIT_CLASS_CHATTR_32 , sparc32_chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL_32 , sparc32_signal_class);#endif audit_register_class (AUDIT_CLASS_WRITE , write_class);audit_register_class (AUDIT_CLASS_READ , read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class);audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL , signal_class);return 0 ; }
arch/sparc64/kernel/compat_audit.c +5 -0
@@ -20,6 +20,11 @@ unsigned sparc32_read_class[] = { ~0U }; +unsigned sparc32_signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int sparc32_classify_syscall (unsigned syscall) {switch (syscall) {
arch/x86_64/ia32/audit.c +5 -0
@@ -20,6 +20,11 @@ unsigned ia32_read_class[] = { ~0U }; +unsigned ia32_signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int ia32_classify_syscall (unsigned syscall) {switch (syscall) {
arch/x86_64/kernel/audit.c +8 -0
@@ -23,6 +23,11 @@ static unsigned chattr_class[] = { ~0U }; +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_IA32_EMULATION
@@ -49,15 +54,18 @@ static int __init audit_classes_init(void)extern __u32 ia32_write_class[];extern __u32 ia32_read_class[];extern __u32 ia32_chattr_class[]; +extern __u32 ia32_signal_class[];audit_register_class (AUDIT_CLASS_WRITE_32 , ia32_write_class);audit_register_class (AUDIT_CLASS_READ_32 , ia32_read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE_32 , ia32_dir_class);audit_register_class (AUDIT_CLASS_CHATTR_32 , ia32_chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL_32 , ia32_signal_class);#endif audit_register_class (AUDIT_CLASS_WRITE , write_class);audit_register_class (AUDIT_CLASS_READ , read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class);audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL , signal_class);return 0 ; }
include/asm-generic/audit_signal.h new file +3 -0
@@ -0,0 +1,3 @@ +__NR_kill, +__NR_tgkill, +__NR_tkill,
include/linux/audit.h +2 -0
@@ -147,6 +147,8 @@#define AUDIT_CLASS_READ_32 5#define AUDIT_CLASS_WRITE 6#define AUDIT_CLASS_WRITE_32 7 +#define AUDIT_CLASS_SIGNAL 8 +#define AUDIT_CLASS_SIGNAL_32 9/* This bitmask is used to validate user input. It represents all bits that * are currently used in an audit field constant understood by the kernel.
lib/audit.c +6 -0
@@ -23,6 +23,11 @@ static unsigned chattr_class[] = { ~0U }; +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; +int audit_classify_syscall (int abi,unsigned syscall) {switch (syscall) {
@@ -49,6 +54,7 @@ static int __init audit_classes_init(void)audit_register_class (AUDIT_CLASS_READ , read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class);audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +audit_register_class (AUDIT_CLASS_SIGNAL , signal_class);return 0 ; }
Signature · 1 line
1.4.4.4
PATCH 2/2 audit signal recipients (v2)
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. Move the audit_signal_info() hook up in check_kill_permission() so we audit attempts where permission is denied.
--- include/linux/audit.h | 3 ++ kernel/audit.h | 12 ++++--- kernel/auditfilter.c | 14 ++++++++- kernel/auditsc.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++-- kernel/signal.c | 10 ++++-- 5 files changed, 100 insertions(+), 15 deletions(-)
include/linux/audit.h +3 -0
@@ -90,6 +90,7 @@#define AUDIT_MQ_GETSETATTR 1315/* POSIX MQ get/set attribute record type */ #define AUDIT_KERNEL_OTHER 1316/* For use by 3rd party modules */ #define AUDIT_FD_PAIR 1317/* audit record for pipe/socketpair */ +#define AUDIT_TARGET_PID 1318/* audit record for a pid arg */ #define AUDIT_AVC 1400/* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401/* Internal SE Linux Errors */
@@ -443,6 +444,7 @@ static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) return 0; }extern int audit_n_rules; +extern int audit_signals;#else #define audit_alloc (t) ({ 0; })#define audit_free (t) do { ; } while (0)
@@ -472,6 +474,7 @@ extern int audit_n_rules;#define audit_mq_notify (d,n) ({ 0; })#define audit_mq_getsetattr (d,s) ({ 0; })#define audit_n_rules 0 +#define audit_signals 0#endif #ifdef CONFIG_AUDIT
kernel/audit.h +7 -5
@@ -131,17 +131,19 @@ extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32,extern int selinux_audit_rule_update (void );#ifdef CONFIG_AUDITSYSCALL -extern void __audit_signal_info (int sig,struct task_struct *t); -static inline void audit_signal_info (int sig,struct task_struct *t) +extern int __audit_signal_info (int sig,struct task_struct *t); +static inline int audit_signal_info (int sig,struct task_struct *t) { -if (unlikely (audit_pid && t->tgid == audit_pid)) -__audit_signal_info (sig, t); +if (unlikely ((audit_pid && t->tgid == audit_pid) || + (audit_signals && !audit_dummy_context ()))) +return __audit_signal_info (sig, t); +return 0 ; }extern enum audit_state audit_filter_inodes (struct task_struct *,struct audit_context *);extern void audit_set_auditable (struct audit_context *);#else -#define audit_signal_info (s,t) +#define audit_signal_info (s,t) AUDIT_DISABLED#define audit_filter_inodes (t,c) AUDIT_DISABLED#define audit_set_auditable (c)#endif
kernel/auditfilter.c +12 -2
@@ -1171,7 +1171,7 @@ static inline int audit_add_rule(struct audit_entry *entry,struct nameidata *ndp, *ndw;int h, err, putnd_needed =0 ;#ifdef CONFIG_AUDITSYSCALL -int dont_count =0 ; +int i, dont_count =0 ;/* If either of these, don't count towards total */ if (entry->rule.listnr == AUDIT_FILTER_USER ||
@@ -1221,6 +1221,11 @@ static inline int audit_add_rule(struct audit_entry *entry,#ifdef CONFIG_AUDITSYSCALL if (!dont_count) audit_n_rules++; + +for (i =0 ; i <AUDIT_BITMASK_SIZE ; i++) +if ((entry->rule.mask[i] & classes[AUDIT_CLASS_SIGNAL ][i]) || + (entry->rule.mask[i] & classes[AUDIT_CLASS_SIGNAL_32 ][i])) + audit_signals++;#endif mutex_unlock (&audit_filter_mutex);
@@ -1247,7 +1252,7 @@ static inline int audit_del_rule(struct audit_entry *entry,LIST_HEAD (inotify_list);int h, ret =0 ;#ifdef CONFIG_AUDITSYSCALL -int dont_count =0 ; +int i, dont_count =0 ;/* If either of these, don't count towards total */ if (entry->rule.listnr == AUDIT_FILTER_USER ||
@@ -1294,6 +1299,11 @@ static inline int audit_del_rule(struct audit_entry *entry,#ifdef CONFIG_AUDITSYSCALL if (!dont_count) audit_n_rules--; + +for (i =0 ; i <AUDIT_BITMASK_SIZE ; i++) +if ((entry->rule.mask[i] & classes[AUDIT_CLASS_SIGNAL ][i]) || + (entry->rule.mask[i] & classes[AUDIT_CLASS_SIGNAL_32 ][i])) + audit_signals--;#endif mutex_unlock (&audit_filter_mutex);
kernel/auditsc.c +72 -4
121 lines not on this page · raw message
kernel/signal.c +6 -4
@@ -607,6 +607,11 @@ static int check_kill_permission(int sig, struct siginfo *info,int error = -EINVAL ;if (!valid_signal (sig))return error; + + error =audit_signal_info (sig, t);/* Let audit system see the signal */ +if (error) +return error; + error = -EPERM ; if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info))) && ((sig != SIGCONT) ||
@@ -616,10 +621,7 @@ static int check_kill_permission(int sig, struct siginfo *info, && !capable(CAP_KILL))return error; - error =security_task_kill (t, info, sig,0 ); -if (!error) -audit_signal_info (sig, t);/* Let audit system see the signal */ -return error; +return security_task_kill (t, info, sig,0 ); }/* forward decl */
Signature · 1 line
1.4.4.4
Eric Paris
maintainerRe: [PATCH 2/2] audit signal recipients (v2)
Quoted 35 lines · Amy Griffis
kernel/auditfilter.c +7
-2@@ -1171,7 +1171,7 @@ static inline int audit_add_rule(struct audit_entry *entry,struct nameidata *ndp, *ndw;int h, err, putnd_needed =0 ;#ifdef CONFIG_AUDITSYSCALL -int dont_count =0 ; +int i, dont_count =0 ;/* If either of these, don't count towards total */ if (entry->rule.listnr == AUDIT_FILTER_USER ||@@ -1221,6 +1221,11 @@ static inline int audit_add_rule(struct audit_entry *entry,#ifdef CONFIG_AUDITSYSCALL if (!dont_count) audit_n_rules++; + +for (i =0 ; i <AUDIT_BITMASK_SIZE ; i++) +if ((entry->rule.mask[i] & classes[AUDIT_CLASS_SIGNAL ][i]) || + (entry->rule.mask[i] & classes[AUDIT_CLASS_SIGNAL_32 ][i])) + audit_signals++;#endif mutex_unlock (&audit_filter_mutex);@@ -1247,7 +1252,7 @@ static inline int audit_del_rule(struct audit_entry *entry,LIST_HEAD (inotify_list);int h, ret =0 ;#ifdef CONFIG_AUDITSYSCALL -int dont_count =0 ; +int i, dont_count =0 ;/* If either of these, don't count towards total */ if (entry->rule.listnr == AUDIT_FILTER_USER ||
kernel/auditfilter.c static inline int audit_del_rule(struct audit_entry *entry, · line 1308
Quoted 10 lines
kernel/auditfilter.c +5
-0@@ -1294,6 +1299,11 @@ static inline int audit_del_rule(struct audit_entry *entry,#ifdef CONFIG_AUDITSYSCALL if (!dont_count) audit_n_rules--; + +for (i =0 ; i <AUDIT_BITMASK_SIZE ; i++) +if ((entry->rule.mask[i] & classes[AUDIT_CLASS_SIGNAL ][i]) || + (entry->rule.mask[i] & classes[AUDIT_CLASS_SIGNAL_32 ][i])) + audit_signals--;#endif mutex_unlock (&audit_filter_mutex);
Since AUDIT_CLASS_SIGNAL_32 is not defined on i686 (see patch 1/2 the patch to lib/audit.c which i686 uses) the second part of this or statement is referencing way beyond the end of the classes array. I'm investigating the right way to decide what we should be comparing against across all arches, but maybe you will find it first.
-Eric