signal audit (v3)
Subsystems (5)
cover signal audit (v3)
Several changes since last version:
- use arch rule field to determine which signal class to check, check both if arch is unspecified
- don't check AUDIT_CLASS_SIGNAL_32 if it doesn't exist
- group target pids in aux structs (initially 16)
- on syscall exit, initialize context's aux ptrs for re-use
- don't convert sid to string until we log a record
Applies on top of ptrace patch.
PATCH 1/2 add SIGNAL syscall class (v3)
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
@@ -149,6 +149,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 (v3)
In reply to Amy GriffisWhen 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.
--- arch/ia64/kernel/audit.c | 9 +++ arch/powerpc/kernel/audit.c | 9 +++ arch/s390/kernel/audit.c | 9 +++ arch/sparc64/kernel/audit.c | 9 +++ arch/x86_64/kernel/audit.c | 9 +++ include/linux/audit.h | 3 + kernel/audit.h | 13 +++-- kernel/auditfilter.c | 48 +++++++++++++++++- kernel/auditsc.c | 116 ++++++++++++++++++++++++++++++++++-------- kernel/signal.c | 10 ++-- lib/audit.c | 5 ++ 11 files changed, 208 insertions(+), 32 deletions(-)
arch/ia64/kernel/audit.c +9 -0
@@ -28,6 +28,15 @@ static unsigned signal_class[] = { ~0U }; +int audit_classify_arch (int arch) +{ +#ifdef CONFIG_IA32_SUPPORT +if (arch ==AUDIT_ARCH_I386 ) +return 1 ; +#endif +return 0 ; +} +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_IA32_SUPPORT
arch/powerpc/kernel/audit.c +9 -0
@@ -28,6 +28,15 @@ static unsigned signal_class[] = { ~0U }; +int audit_classify_arch (int arch) +{ +#ifdef CONFIG_PPC64 +if (arch ==AUDIT_ARCH_PPC ) +return 1 ; +#endif +return 0 ; +} +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_PPC64
arch/s390/kernel/audit.c +9 -0
@@ -28,6 +28,15 @@ static unsigned signal_class[] = { ~0U }; +int audit_classify_arch (int arch) +{ +#ifdef CONFIG_COMPAT +if (arch ==AUDIT_ARCH_S390 ) +return 1 ; +#endif +return 0 ; +} +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_COMPAT
arch/sparc64/kernel/audit.c +9 -0
@@ -28,6 +28,15 @@ static unsigned signal_class[] = { ~0U }; +int audit_classify_arch (int arch) +{ +#ifdef CONFIG_SPARC32_COMPAT +if (arch ==AUDIT_ARCH_SPARC ) +return 1 ; +#endif +return 0 ; +} +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_SPARC32_COMPAT
arch/x86_64/kernel/audit.c +9 -0
@@ -28,6 +28,15 @@ static unsigned signal_class[] = { ~0U }; +int audit_classify_arch (int arch) +{ +#ifdef CONFIG_IA32_EMULATION +if (arch ==AUDIT_ARCH_I386 ) +return 1 ; +#endif +return 0 ; +} +int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_IA32_EMULATION
include/linux/audit.h +3 -0
@@ -344,6 +344,7 @@ struct mqstat;#define AUDITSC_RESULT (x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )extern int __init audit_register_class (int class,unsigned *list);extern int audit_classify_syscall (int abi,unsigned syscall); +extern int audit_classify_arch (int arch);#ifdef CONFIG_AUDITSYSCALL /* These are defined in auditsc.c */ /* Public API */
@@ -456,6 +457,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)
@@ -486,6 +488,7 @@ extern int audit_n_rules;#define audit_mq_getsetattr (d,s) ({ 0; })#define audit_ptrace (t) ((void)0)#define audit_n_rules 0 +#define audit_signals 0#endif #ifdef CONFIG_AUDIT
kernel/audit.h +8 -5
@@ -83,6 +83,7 @@ struct audit_krule {u32 field_count;char *filterkey;/* ties events to rules */ struct audit_field *fields; +struct audit_field *arch_f;/* quick access to arch field */ struct audit_field *inode_f;/* quick access to an inode field */ struct audit_watch *watch;/* associated watch */ struct list_head rlist;/* entry in audit_watch.rules list */
@@ -131,17 +132,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 +47 -1
84 lines not on this page · raw message
kernel/auditsc.c +94 -22
202 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 */
lib/audit.c +5 -0
@@ -28,6 +28,11 @@ static unsigned signal_class[] = { ~0U }; +int audit_classify_arch (int arch) +{ +return 0 ; +} +int audit_classify_syscall (int abi,unsigned syscall) {switch (syscall) {
Signature · 1 line
1.4.4.4