diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2006-07-01 03:56:16 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-07-01 07:44:10 -0400 |
commit | b915543b46a2aa599fdd2169e51bcfd88812a12b (patch) | |
tree | 8025e6654829d4c245b5b6b6f47a84543ebffb7b | |
parent | 6e5a2d1d32596850a0ebf7fb3e54c0d69901dabd (diff) |
[PATCH] 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 <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/i386/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/i386/kernel/audit.c | 23 | ||||
-rw-r--r-- | arch/ia64/ia32/Makefile | 1 | ||||
-rw-r--r-- | arch/ia64/ia32/audit.c | 11 | ||||
-rw-r--r-- | arch/ia64/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/audit.c | 29 | ||||
-rw-r--r-- | arch/x86_64/ia32/Makefile | 3 | ||||
-rw-r--r-- | arch/x86_64/ia32/audit.c | 11 | ||||
-rw-r--r-- | arch/x86_64/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/x86_64/kernel/audit.c | 29 | ||||
-rw-r--r-- | include/asm-generic/audit_change_attr.h | 18 | ||||
-rw-r--r-- | include/asm-generic/audit_dir_write.h | 14 | ||||
-rw-r--r-- | include/linux/audit.h | 7 | ||||
-rw-r--r-- | kernel/auditfilter.c | 39 |
14 files changed, 188 insertions, 0 deletions
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 5e70c2fb273a..cbc1184e9473 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -38,6 +38,7 @@ obj-$(CONFIG_VM86) += vm86.o | |||
38 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 38 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
39 | obj-$(CONFIG_HPET_TIMER) += hpet.o | 39 | obj-$(CONFIG_HPET_TIMER) += hpet.o |
40 | obj-$(CONFIG_K8_NB) += k8.o | 40 | obj-$(CONFIG_K8_NB) += k8.o |
41 | obj-$(CONFIG_AUDIT) += audit.o | ||
41 | 42 | ||
42 | EXTRA_AFLAGS := -traditional | 43 | EXTRA_AFLAGS := -traditional |
43 | 44 | ||
diff --git a/arch/i386/kernel/audit.c b/arch/i386/kernel/audit.c new file mode 100644 index 000000000000..5a53c6f371ff --- /dev/null +++ b/arch/i386/kernel/audit.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/audit.h> | ||
4 | #include <asm/unistd.h> | ||
5 | |||
6 | static unsigned dir_class[] = { | ||
7 | #include <asm-generic/audit_dir_write.h> | ||
8 | ~0U | ||
9 | }; | ||
10 | |||
11 | static unsigned chattr_class[] = { | ||
12 | #include <asm-generic/audit_change_attr.h> | ||
13 | ~0U | ||
14 | }; | ||
15 | |||
16 | static int __init audit_classes_init(void) | ||
17 | { | ||
18 | audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); | ||
19 | audit_register_class(AUDIT_CLASS_CHATTR, chattr_class); | ||
20 | return 0; | ||
21 | } | ||
22 | |||
23 | __initcall(audit_classes_init); | ||
diff --git a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile index 61cb60affd95..baad8c7699c0 100644 --- a/arch/ia64/ia32/Makefile +++ b/arch/ia64/ia32/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-y := ia32_entry.o sys_ia32.o ia32_signal.o \ | 5 | obj-y := ia32_entry.o sys_ia32.o ia32_signal.o \ |
6 | ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o | 6 | ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o |
7 | obj-$(CONFIG_AUDIT) += audit.o | ||
7 | 8 | ||
8 | # Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and | 9 | # Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and |
9 | # restore_ia32_fpstate_live() can be sure the live register contain user-level state. | 10 | # restore_ia32_fpstate_live() can be sure the live register contain user-level state. |
diff --git a/arch/ia64/ia32/audit.c b/arch/ia64/ia32/audit.c new file mode 100644 index 000000000000..ab94f2e58cdd --- /dev/null +++ b/arch/ia64/ia32/audit.c | |||
@@ -0,0 +1,11 @@ | |||
1 | #include <asm-i386/unistd.h> | ||
2 | |||
3 | unsigned ia32_dir_class[] = { | ||
4 | #include <asm-generic/audit_dir_write.h> | ||
5 | ~0U | ||
6 | }; | ||
7 | |||
8 | unsigned ia32_chattr_class[] = { | ||
9 | #include <asm-generic/audit_change_attr.h> | ||
10 | ~0U | ||
11 | }; | ||
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 09a0dbc17fb6..0e4553f320bf 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile | |||
@@ -29,6 +29,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/ | |||
29 | obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o | 29 | obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o |
30 | obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o | 30 | obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o |
31 | obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o | 31 | obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o |
32 | obj-$(CONFIG_AUDIT) += audit.o | ||
32 | mca_recovery-y += mca_drv.o mca_drv_asm.o | 33 | mca_recovery-y += mca_drv.o mca_drv_asm.o |
33 | 34 | ||
34 | # The gate DSO image is built using a special linker script. | 35 | # The gate DSO image is built using a special linker script. |
diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c new file mode 100644 index 000000000000..f2512931ccaf --- /dev/null +++ b/arch/ia64/kernel/audit.c | |||
@@ -0,0 +1,29 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/audit.h> | ||
4 | #include <asm/unistd.h> | ||
5 | |||
6 | static unsigned dir_class[] = { | ||
7 | #include <asm-generic/audit_dir_write.h> | ||
8 | ~0U | ||
9 | }; | ||
10 | |||
11 | static unsigned chattr_class[] = { | ||
12 | #include <asm-generic/audit_change_attr.h> | ||
13 | ~0U | ||
14 | }; | ||
15 | |||
16 | static int __init audit_classes_init(void) | ||
17 | { | ||
18 | #ifdef CONFIG_IA32_SUPPORT | ||
19 | extern __u32 ia32_dir_class[]; | ||
20 | extern __u32 ia32_chattr_class[]; | ||
21 | audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ia32_dir_class); | ||
22 | audit_register_class(AUDIT_CLASS_CHATTR_32, ia32_chattr_class); | ||
23 | #endif | ||
24 | audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); | ||
25 | audit_register_class(AUDIT_CLASS_CHATTR, chattr_class); | ||
26 | return 0; | ||
27 | } | ||
28 | |||
29 | __initcall(audit_classes_init); | ||
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile index e9263b4975e0..62bc5f56da9e 100644 --- a/arch/x86_64/ia32/Makefile +++ b/arch/x86_64/ia32/Makefile | |||
@@ -11,6 +11,9 @@ obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) | |||
11 | 11 | ||
12 | obj-$(CONFIG_IA32_AOUT) += ia32_aout.o | 12 | obj-$(CONFIG_IA32_AOUT) += ia32_aout.o |
13 | 13 | ||
14 | audit-class-$(CONFIG_AUDIT) := audit.o | ||
15 | obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y) | ||
16 | |||
14 | $(obj)/syscall32_syscall.o: \ | 17 | $(obj)/syscall32_syscall.o: \ |
15 | $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) | 18 | $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) |
16 | 19 | ||
diff --git a/arch/x86_64/ia32/audit.c b/arch/x86_64/ia32/audit.c new file mode 100644 index 000000000000..ab94f2e58cdd --- /dev/null +++ b/arch/x86_64/ia32/audit.c | |||
@@ -0,0 +1,11 @@ | |||
1 | #include <asm-i386/unistd.h> | ||
2 | |||
3 | unsigned ia32_dir_class[] = { | ||
4 | #include <asm-generic/audit_dir_write.h> | ||
5 | ~0U | ||
6 | }; | ||
7 | |||
8 | unsigned ia32_chattr_class[] = { | ||
9 | #include <asm-generic/audit_change_attr.h> | ||
10 | ~0U | ||
11 | }; | ||
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index aeb9c560be88..819e84ec5b64 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -35,6 +35,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o | |||
35 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o | 35 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o |
36 | obj-$(CONFIG_X86_VSMP) += vsmp.o | 36 | obj-$(CONFIG_X86_VSMP) += vsmp.o |
37 | obj-$(CONFIG_K8_NB) += k8.o | 37 | obj-$(CONFIG_K8_NB) += k8.o |
38 | obj-$(CONFIG_AUDIT) += audit.o | ||
38 | 39 | ||
39 | obj-$(CONFIG_MODULES) += module.o | 40 | obj-$(CONFIG_MODULES) += module.o |
40 | 41 | ||
diff --git a/arch/x86_64/kernel/audit.c b/arch/x86_64/kernel/audit.c new file mode 100644 index 000000000000..a067aa468a85 --- /dev/null +++ b/arch/x86_64/kernel/audit.c | |||
@@ -0,0 +1,29 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/audit.h> | ||
4 | #include <asm/unistd.h> | ||
5 | |||
6 | static unsigned dir_class[] = { | ||
7 | #include <asm-generic/audit_dir_write.h> | ||
8 | ~0U | ||
9 | }; | ||
10 | |||
11 | static unsigned chattr_class[] = { | ||
12 | #include <asm-generic/audit_change_attr.h> | ||
13 | ~0U | ||
14 | }; | ||
15 | |||
16 | static int __init audit_classes_init(void) | ||
17 | { | ||
18 | #ifdef CONFIG_IA32_EMULATION | ||
19 | extern __u32 ia32_dir_class[]; | ||
20 | extern __u32 ia32_chattr_class[]; | ||
21 | audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ia32_dir_class); | ||
22 | audit_register_class(AUDIT_CLASS_CHATTR_32, ia32_chattr_class); | ||
23 | #endif | ||
24 | audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); | ||
25 | audit_register_class(AUDIT_CLASS_CHATTR, chattr_class); | ||
26 | return 0; | ||
27 | } | ||
28 | |||
29 | __initcall(audit_classes_init); | ||
diff --git a/include/asm-generic/audit_change_attr.h b/include/asm-generic/audit_change_attr.h new file mode 100644 index 000000000000..cb05bf69745a --- /dev/null +++ b/include/asm-generic/audit_change_attr.h | |||
@@ -0,0 +1,18 @@ | |||
1 | __NR_chmod, | ||
2 | __NR_fchmod, | ||
3 | __NR_chown, | ||
4 | __NR_fchown, | ||
5 | __NR_lchown, | ||
6 | __NR_setxattr, | ||
7 | __NR_lsetxattr, | ||
8 | __NR_fsetxattr, | ||
9 | __NR_removexattr, | ||
10 | __NR_lremovexattr, | ||
11 | __NR_fremovexattr, | ||
12 | __NR_fchownat, | ||
13 | __NR_fchmodat, | ||
14 | #ifdef __NR_chown32 | ||
15 | __NR_chown32, | ||
16 | __NR_fchown32, | ||
17 | __NR_lchown32, | ||
18 | #endif | ||
diff --git a/include/asm-generic/audit_dir_write.h b/include/asm-generic/audit_dir_write.h new file mode 100644 index 000000000000..161a7a58fbab --- /dev/null +++ b/include/asm-generic/audit_dir_write.h | |||
@@ -0,0 +1,14 @@ | |||
1 | __NR_rename, | ||
2 | __NR_mkdir, | ||
3 | __NR_rmdir, | ||
4 | __NR_creat, | ||
5 | __NR_link, | ||
6 | __NR_unlink, | ||
7 | __NR_symlink, | ||
8 | __NR_mknod, | ||
9 | __NR_mkdirat, | ||
10 | __NR_mknodat, | ||
11 | __NR_unlinkat, | ||
12 | __NR_renameat, | ||
13 | __NR_linkat, | ||
14 | __NR_symlinkat, | ||
diff --git a/include/linux/audit.h b/include/linux/audit.h index c211f0a2abb4..b27d7debc5a1 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -127,6 +127,12 @@ | |||
127 | #define AUDIT_WORD(nr) ((__u32)((nr)/32)) | 127 | #define AUDIT_WORD(nr) ((__u32)((nr)/32)) |
128 | #define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32)) | 128 | #define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32)) |
129 | 129 | ||
130 | #define AUDIT_SYSCALL_CLASSES 16 | ||
131 | #define AUDIT_CLASS_DIR_WRITE 0 | ||
132 | #define AUDIT_CLASS_DIR_WRITE_32 1 | ||
133 | #define AUDIT_CLASS_CHATTR 2 | ||
134 | #define AUDIT_CLASS_CHATTR_32 3 | ||
135 | |||
130 | /* This bitmask is used to validate user input. It represents all bits that | 136 | /* This bitmask is used to validate user input. It represents all bits that |
131 | * are currently used in an audit field constant understood by the kernel. | 137 | * are currently used in an audit field constant understood by the kernel. |
132 | * If you are adding a new #define AUDIT_<whatever>, please ensure that | 138 | * If you are adding a new #define AUDIT_<whatever>, please ensure that |
@@ -307,6 +313,7 @@ struct mqstat; | |||
307 | #define AUDITSC_SUCCESS 1 | 313 | #define AUDITSC_SUCCESS 1 |
308 | #define AUDITSC_FAILURE 2 | 314 | #define AUDITSC_FAILURE 2 |
309 | #define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS ) | 315 | #define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS ) |
316 | extern int __init audit_register_class(int class, unsigned *list); | ||
310 | #ifdef CONFIG_AUDITSYSCALL | 317 | #ifdef CONFIG_AUDITSYSCALL |
311 | /* These are defined in auditsc.c */ | 318 | /* These are defined in auditsc.c */ |
312 | /* Public API */ | 319 | /* Public API */ |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 7f2ea8b84a27..5b4e16276ca0 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -279,6 +279,29 @@ static int audit_to_watch(struct audit_krule *krule, char *path, int len, | |||
279 | return 0; | 279 | return 0; |
280 | } | 280 | } |
281 | 281 | ||
282 | static __u32 *classes[AUDIT_SYSCALL_CLASSES]; | ||
283 | |||
284 | int __init audit_register_class(int class, unsigned *list) | ||
285 | { | ||
286 | __u32 *p = kzalloc(AUDIT_BITMASK_SIZE * sizeof(__u32), GFP_KERNEL); | ||
287 | if (!p) | ||
288 | return -ENOMEM; | ||
289 | while (*list != ~0U) { | ||
290 | unsigned n = *list++; | ||
291 | if (n >= AUDIT_BITMASK_SIZE * 32 - AUDIT_SYSCALL_CLASSES) { | ||
292 | kfree(p); | ||
293 | return -EINVAL; | ||
294 | } | ||
295 | p[AUDIT_WORD(n)] |= AUDIT_BIT(n); | ||
296 | } | ||
297 | if (class >= AUDIT_SYSCALL_CLASSES || classes[class]) { | ||
298 | kfree(p); | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | classes[class] = p; | ||
302 | return 0; | ||
303 | } | ||
304 | |||
282 | /* Common user-space to kernel rule translation. */ | 305 | /* Common user-space to kernel rule translation. */ |
283 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | 306 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) |
284 | { | 307 | { |
@@ -322,6 +345,22 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | |||
322 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) | 345 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) |
323 | entry->rule.mask[i] = rule->mask[i]; | 346 | entry->rule.mask[i] = rule->mask[i]; |
324 | 347 | ||
348 | for (i = 0; i < AUDIT_SYSCALL_CLASSES; i++) { | ||
349 | int bit = AUDIT_BITMASK_SIZE * 32 - i - 1; | ||
350 | __u32 *p = &entry->rule.mask[AUDIT_WORD(bit)]; | ||
351 | __u32 *class; | ||
352 | |||
353 | if (!(*p & AUDIT_BIT(bit))) | ||
354 | continue; | ||
355 | *p &= ~AUDIT_BIT(bit); | ||
356 | class = classes[i]; | ||
357 | if (class) { | ||
358 | int j; | ||
359 | for (j = 0; j < AUDIT_BITMASK_SIZE; j++) | ||
360 | entry->rule.mask[j] |= class[j]; | ||
361 | } | ||
362 | } | ||
363 | |||
325 | return entry; | 364 | return entry; |
326 | 365 | ||
327 | exit_err: | 366 | exit_err: |