audit syscall classes
Subsystems (2)
PATCH 1/1 audit syscall classes
Allow to tie upper bits of syscall bitmap in audit rules to kernel-defined sets of syscalls. Infrastructure, a couple of classes (with 32bit counterparts for biarch targets) and actual tie-in on i386, amd64 and ia64.
Signed-off-by Al Viro <[email protected]>
---
arch/i386/kernel/Makefile | 1 + arch/i386/kernel/audit.c | 23 ++++++++++++++++++ arch/ia64/ia32/Makefile | 1 + arch/ia64/ia32/audit.c | 11 +++++++++ arch/ia64/kernel/Makefile | 1 + arch/ia64/kernel/audit.c | 29 +++++++++++++++++++++++ arch/x86_64/ia32/Makefile | 3 ++ arch/x86_64/ia32/audit.c | 11 +++++++++ arch/x86_64/kernel/Makefile | 1 + arch/x86_64/kernel/audit.c | 29 +++++++++++++++++++++++ include/asm-generic/audit_change_attr.h | 18 ++++++++++++++ include/asm-generic/audit_dir_write.h | 14 +++++++++++ include/linux/audit.h | 7 ++++++ kernel/auditfilter.c | 39 +++++++++++++++++++++++++++++++ 14 files changed, 188 insertions(+), 0 deletions(-) create mode 100644 arch/i386/kernel/audit.c create mode 100644 arch/ia64/ia32/audit.c create mode 100644 arch/ia64/kernel/audit.c create mode 100644 arch/x86_64/ia32/audit.c create mode 100644 arch/x86_64/kernel/audit.c create mode 100644 include/asm-generic/audit_change_attr.h create mode 100644 include/asm-generic/audit_dir_write.h
b915543b46a2aa599fdd2169e51bcfd88812a12b
arch/i386/kernel/Makefile +1 -0
@@ -38,6 +38,7 @@ obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o +obj-$(CONFIG_AUDIT) += audit.o EXTRA_AFLAGS := -traditional
arch/i386/kernel/audit.c new file +23 -0
@@ -0,0 +1,23 @@ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/audit.h> +#include <asm/unistd.h> + +static unsigned dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +static unsigned chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +static int __init audit_classes_init (void ) +{ +audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class); +audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +return 0 ; +} + +__initcall (audit_classes_init);
arch/ia64/ia32/Makefile +1 -0
@@ -4,6 +4,7 @@ # obj-y := ia32_entry.o sys_ia32.o ia32_signal.o \ ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o +obj-$(CONFIG_AUDIT) += audit.o # Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and # restore_ia32_fpstate_live() can be sure the live register contain user-level state.
arch/ia64/ia32/audit.c new file +11 -0
@@ -0,0 +1,11 @@ +#include <asm-i386/unistd.h> + +unsigned ia32_dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +unsigned ia32_chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +};
arch/ia64/kernel/Makefile +1 -0
@@ -29,6 +29,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o +obj-$(CONFIG_AUDIT) += audit.o mca_recovery-y += mca_drv.o mca_drv_asm.o # The gate DSO image is built using a special linker script.
arch/ia64/kernel/audit.c new file +29 -0
@@ -0,0 +1,29 @@ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/audit.h> +#include <asm/unistd.h> + +static unsigned dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +static unsigned chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +static int __init audit_classes_init (void ) +{ +#ifdef CONFIG_IA32_SUPPORT +extern __u32 ia32_dir_class[]; +extern __u32 ia32_chattr_class[]; +audit_register_class (AUDIT_CLASS_DIR_WRITE_32 , ia32_dir_class); +audit_register_class (AUDIT_CLASS_CHATTR_32 , ia32_chattr_class); +#endif +audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class); +audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +return 0 ; +} + +__initcall (audit_classes_init);
arch/x86_64/ia32/Makefile +3 -0
@@ -11,6 +11,9 @@ obj-$(CONFIG_IA32_EMULATION) += $(sysv-y obj-$(CONFIG_IA32_AOUT) += ia32_aout.o +audit-class-$(CONFIG_AUDIT) := audit.o +obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y) + $(obj)/syscall32_syscall.o: \ $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so)
arch/x86_64/ia32/audit.c new file +11 -0
@@ -0,0 +1,11 @@ +#include <asm-i386/unistd.h> + +unsigned ia32_dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +unsigned ia32_chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +};
arch/x86_64/kernel/Makefile +1 -0
@@ -35,6 +35,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o obj-$(CONFIG_X86_VSMP) += vsmp.o obj-$(CONFIG_K8_NB) += k8.o +obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_MODULES) += module.o
arch/x86_64/kernel/audit.c new file +29 -0
@@ -0,0 +1,29 @@ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/audit.h> +#include <asm/unistd.h> + +static unsigned dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +static unsigned chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +static int __init audit_classes_init (void ) +{ +#ifdef CONFIG_IA32_EMULATION +extern __u32 ia32_dir_class[]; +extern __u32 ia32_chattr_class[]; +audit_register_class (AUDIT_CLASS_DIR_WRITE_32 , ia32_dir_class); +audit_register_class (AUDIT_CLASS_CHATTR_32 , ia32_chattr_class); +#endif +audit_register_class (AUDIT_CLASS_DIR_WRITE , dir_class); +audit_register_class (AUDIT_CLASS_CHATTR , chattr_class); +return 0 ; +} + +__initcall (audit_classes_init);
include/asm-generic/audit_change_attr.h new file +18 -0
@@ -0,0 +1,18 @@ +__NR_chmod, +__NR_fchmod, +__NR_chown, +__NR_fchown, +__NR_lchown, +__NR_setxattr, +__NR_lsetxattr, +__NR_fsetxattr, +__NR_removexattr, +__NR_lremovexattr, +__NR_fremovexattr, +__NR_fchownat, +__NR_fchmodat, +#ifdef __NR_chown32 +__NR_chown32, +__NR_fchown32, +__NR_lchown32, +#endif
include/asm-generic/audit_dir_write.h new file +14 -0
@@ -0,0 +1,14 @@ +__NR_rename, +__NR_mkdir, +__NR_rmdir, +__NR_creat, +__NR_link, +__NR_unlink, +__NR_symlink, +__NR_mknod, +__NR_mkdirat, +__NR_mknodat, +__NR_unlinkat, +__NR_renameat, +__NR_linkat, +__NR_symlinkat,
include/linux/audit.h +7 -0
@@ -127,6 +127,12 @@ #define AUDIT_BITMASK_SIZE 64#define AUDIT_WORD (nr) ((__u32)((nr)/32))#define AUDIT_BIT (nr) (1 << ((nr) - AUDIT_WORD(nr)*32)) +#define AUDIT_SYSCALL_CLASSES 16 +#define AUDIT_CLASS_DIR_WRITE 0 +#define AUDIT_CLASS_DIR_WRITE_32 1 +#define AUDIT_CLASS_CHATTR 2 +#define AUDIT_CLASS_CHATTR_32 3 +/* 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. * If you are adding a new #define AUDIT_<whatever>, please ensure that
@@ -307,6 +313,7 @@ #define AUDITSC_INVALID 0#define AUDITSC_SUCCESS 1#define AUDITSC_FAILURE 2#define AUDITSC_RESULT (x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS ) +extern int __init audit_register_class (int class,unsigned *list);#ifdef CONFIG_AUDITSYSCALL /* These are defined in auditsc.c */ /* Public API */
kernel/auditfilter.c +39 -0
@@ -279,6 +279,29 @@ static int audit_to_watch(struct audit_kreturn 0 ; } +static __u32 *classes[AUDIT_SYSCALL_CLASSES ]; + +int __init audit_register_class (int class,unsigned *list) +{ +__u32 *p =kzalloc (AUDIT_BITMASK_SIZE *sizeof (__u32),GFP_KERNEL ); +if (!p) +return -ENOMEM ; +while (*list != ~0U ) { +unsigned n = *list++; +if (n >=AUDIT_BITMASK_SIZE *32 -AUDIT_SYSCALL_CLASSES ) { +kfree (p); +return -EINVAL ; + } + p[AUDIT_WORD (n)] |=AUDIT_BIT (n); + } +if (class >=AUDIT_SYSCALL_CLASSES || classes[class]) { +kfree (p); +return -EINVAL ; + } + classes[class] = p; +return 0 ; +} +/* Common user-space to kernel rule translation. */ static inline struct audit_entry *audit_to_entry_common (struct audit_rule *rule) {
@@ -322,6 +345,22 @@ #endiffor (i =0 ; i <AUDIT_BITMASK_SIZE ; i++) entry->rule.mask[i] = rule->mask[i]; +for (i =0 ; i <AUDIT_SYSCALL_CLASSES ; i++) { +int bit =AUDIT_BITMASK_SIZE *32 - i -1 ; +__u32 *p = &entry->rule.mask[AUDIT_WORD (bit)]; +__u32 *class; + +if (!(*p &AUDIT_BIT (bit))) +continue ; + *p &= ~AUDIT_BIT (bit); + class = classes[i]; +if (class) { +int j; +for (j =0 ; j <AUDIT_BITMASK_SIZE ; j++) + entry->rule.mask[j] |= class[j]; + } + } +return entry; exit_err:
Signature · 1 line
1.3.GIT
include/linux/audit.h #define AUDIT_BITMASK_SIZE 64 · line 134
Quoted 5 lines · Alexander Viro
include/linux/audit.h +5
-0+#define AUDIT_SYSCALL_CLASSES 16 +#define AUDIT_CLASS_DIR_WRITE 0 +#define AUDIT_CLASS_DIR_WRITE_32 1 +#define AUDIT_CLASS_CHATTR 2 +#define AUDIT_CLASS_CHATTR_32 3
Hello,
I'm working on the auditctl support for this right now. The requirements are
simply: read, write, execute, and attribute change. How do I get it from the above? I don't see anything for reads or execute. Also, why is DIR in the name of writes? Is this limited to notification of DIRS?
Thanks,
-Steve