[PATCH] fix ppid bug in 2.6.18 kernel
by Steve Grubb
Hello,
During some troubleshooting, I found that ppid was accidentally omitted from
the legacy rule section. This resulted in EINVAL for any rule with ppid sent
with AUDIT_ADD.
Signed-off-by: Steve Grubb <sgrubb(a)redhat.com>
diff -urp linux-2.6.17.x86_64.orig/kernel/auditfilter.c linux-2.6.17.x86_64/kernel/auditfilter.c
--- linux-2.6.17.x86_64.orig/kernel/auditfilter.c 2006-08-26 13:50:19.000000000 -0400
+++ linux-2.6.17.x86_64/kernel/auditfilter.c 2006-08-26 13:52:30.000000000 -0400
@@ -413,6 +413,7 @@ static struct audit_entry *audit_rule_to
case AUDIT_PERS:
case AUDIT_ARCH:
case AUDIT_MSGTYPE:
+ case AUDIT_PPID:
case AUDIT_DEVMAJOR:
case AUDIT_DEVMINOR:
case AUDIT_EXIT:
18 years, 3 months
audit 1.2.6 released
by Steve Grubb
Hi,
I've just released a new version of the audit daemon. It can be downloaded
from http://people.redhat.com/sgrubb/audit It will also be in rawhide
tomorrow. The Changelog is:
- Apply updates to dispatcher
- Fix a couple bugs regarding MLS labels
- Resurrect -p option
- Tighten rules with exclude filter
- Fix parsing issue which lead to segfault in some cases
- Fix option parsing to ignore malformed lines
Please let me know if there are any problems with this release.
-Steve
18 years, 4 months
exclude's effect with multiple rules
by Michael C Thompson
Hey all,
So if I have the following two rules, what should be expected behaviour?
auditctl -a entry,always -S chmod
auditctl -a exclude,always -S all
... Assume we can change the ordering.
Thanks,
Mike
18 years, 4 months
AUDIT_PERM support
by Alexander Viro
* two new classes (and their 32bit counterparts) added (READ, WRITE)
* new predicate (AUDIT_PERM) to be used with AUDIT_WATCH. True
if given kind of access being attempted; f->val is a bitmask, bits are
1 - exec
2 - write
4 - read
8 - attributes modification
A few syscalls are dubious: ftruncate, fsync, fdatasync, sync_file_range
all need opening for write, so they might be removed from WRITE class.
Note that normal file IO (and directory reads) are _not_ included - logging
them on those rules would result in logging storms and give no new information
since we would catch the corresponding open() anyway.
diff --git a/arch/i386/kernel/audit.c b/arch/i386/kernel/audit.c
index 5a53c6f..3b97cff 100644
--- a/arch/i386/kernel/audit.c
+++ b/arch/i386/kernel/audit.c
@@ -8,13 +8,41 @@ #include <asm-generic/audit_dir_write.h>
~0U
};
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
static unsigned chattr_class[] = {
#include <asm-generic/audit_change_attr.h>
~0U
};
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+ switch(syscall) {
+ case __NR_open:
+ return 2;
+ case __NR_openat:
+ return 3;
+ case __NR_socketcall:
+ return 4;
+ case __NR_execve:
+ return 5;
+ default:
+ return 0;
+ }
+}
+
static int __init audit_classes_init(void)
{
+ 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);
return 0;
diff --git a/arch/ia64/ia32/audit.c b/arch/ia64/ia32/audit.c
index ab94f2e..92d7d0c 100644
--- a/arch/ia64/ia32/audit.c
+++ b/arch/ia64/ia32/audit.c
@@ -9,3 +9,29 @@ unsigned ia32_chattr_class[] = {
#include <asm-generic/audit_change_attr.h>
~0U
};
+
+unsigned ia32_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned ia32_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+int ia32_classify_syscall(unsigned syscall)
+{
+ switch(syscall) {
+ case __NR_open:
+ return 2;
+ case __NR_openat:
+ return 3;
+ case __NR_socketcall:
+ return 4;
+ case __NR_execve:
+ return 5;
+ default:
+ return 1;
+ }
+}
diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c
index f251293..21f3338 100644
--- a/arch/ia64/kernel/audit.c
+++ b/arch/ia64/kernel/audit.c
@@ -8,19 +8,54 @@ #include <asm-generic/audit_dir_write.h>
~0U
};
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
static unsigned chattr_class[] = {
#include <asm-generic/audit_change_attr.h>
~0U
};
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_IA32_EMULATION
+ extern int ia32_classify_syscall(unsigned);
+ if (abi == AUDIT_ARCH_I386)
+ return ia32_classify_syscall(syscall);
+#endif
+ switch(syscall) {
+ case __NR_open:
+ return 2;
+ case __NR_openat:
+ return 3;
+ case __NR_execve:
+ return 5;
+ default:
+ return 0;
+ }
+}
+
static int __init audit_classes_init(void)
{
-#ifdef CONFIG_IA32_SUPPORT
+#ifdef CONFIG_IA32_EMULATION
extern __u32 ia32_dir_class[];
+ extern __u32 ia32_write_class[];
+ extern __u32 ia32_read_class[];
extern __u32 ia32_chattr_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);
#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);
return 0;
diff --git a/arch/x86_64/ia32/audit.c b/arch/x86_64/ia32/audit.c
index ab94f2e..92d7d0c 100644
--- a/arch/x86_64/ia32/audit.c
+++ b/arch/x86_64/ia32/audit.c
@@ -9,3 +9,29 @@ unsigned ia32_chattr_class[] = {
#include <asm-generic/audit_change_attr.h>
~0U
};
+
+unsigned ia32_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned ia32_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+int ia32_classify_syscall(unsigned syscall)
+{
+ switch(syscall) {
+ case __NR_open:
+ return 2;
+ case __NR_openat:
+ return 3;
+ case __NR_socketcall:
+ return 4;
+ case __NR_execve:
+ return 5;
+ default:
+ return 1;
+ }
+}
diff --git a/arch/x86_64/kernel/audit.c b/arch/x86_64/kernel/audit.c
index a067aa4..21f3338 100644
--- a/arch/x86_64/kernel/audit.c
+++ b/arch/x86_64/kernel/audit.c
@@ -8,19 +8,54 @@ #include <asm-generic/audit_dir_write.h>
~0U
};
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
static unsigned chattr_class[] = {
#include <asm-generic/audit_change_attr.h>
~0U
};
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_IA32_EMULATION
+ extern int ia32_classify_syscall(unsigned);
+ if (abi == AUDIT_ARCH_I386)
+ return ia32_classify_syscall(syscall);
+#endif
+ switch(syscall) {
+ case __NR_open:
+ return 2;
+ case __NR_openat:
+ return 3;
+ case __NR_execve:
+ return 5;
+ default:
+ return 0;
+ }
+}
+
static int __init audit_classes_init(void)
{
#ifdef CONFIG_IA32_EMULATION
extern __u32 ia32_dir_class[];
+ extern __u32 ia32_write_class[];
+ extern __u32 ia32_read_class[];
extern __u32 ia32_chattr_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);
#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);
return 0;
diff --git a/include/asm-generic/audit_read.h b/include/asm-generic/audit_read.h
new file mode 100644
index 0000000..0e87464
--- /dev/null
+++ b/include/asm-generic/audit_read.h
@@ -0,0 +1,8 @@
+__NR_readlink,
+__NR_quotactl,
+__NR_listxattr,
+__NR_llistxattr,
+__NR_flistxattr,
+__NR_getxattr,
+__NR_lgetxattr,
+__NR_fgetxattr,
diff --git a/include/asm-generic/audit_write.h b/include/asm-generic/audit_write.h
new file mode 100644
index 0000000..affc7a1
--- /dev/null
+++ b/include/asm-generic/audit_write.h
@@ -0,0 +1,18 @@
+#include <asm-generic/audit_dir_write.h>
+__NR_acct,
+__NR_swapon,
+__NR_quotactl,
+__NR_truncate,
+#ifdef __NR_truncate64
+__NR_truncate64,
+__NR_ftruncate64, /* ? */
+#endif
+__NR_fsync, /* ? */
+__NR_fdatasync, /* ? */
+__NR_ftruncate, /* ? */
+#ifdef __NR_sync_file_range
+__NR_sync_file_range, /* ? */
+#endif
+#ifdef __NR_bind
+__NR_bind, /* bind can affect fs object only in one way... */
+#endif
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 64f9f9e..e947e67 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -132,6 +132,10 @@ #define AUDIT_CLASS_DIR_WRITE 0
#define AUDIT_CLASS_DIR_WRITE_32 1
#define AUDIT_CLASS_CHATTR 2
#define AUDIT_CLASS_CHATTR_32 3
+#define AUDIT_CLASS_READ 4
+#define AUDIT_CLASS_READ_32 5
+#define AUDIT_CLASS_WRITE 6
+#define AUDIT_CLASS_WRITE_32 7
/* 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.
@@ -177,6 +181,7 @@ #define AUDIT_INODE 102
#define AUDIT_EXIT 103
#define AUDIT_SUCCESS 104 /* exit >= 0; value ignored */
#define AUDIT_WATCH 105
+#define AUDIT_PERM 106
#define AUDIT_ARG0 200
#define AUDIT_ARG1 (AUDIT_ARG0+1)
@@ -314,6 +319,7 @@ #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);
+extern int audit_classify_syscall(int abi, unsigned syscall);
#ifdef CONFIG_AUDITSYSCALL
/* These are defined in auditsc.c */
/* Public API */
diff --git a/kernel/audit.h b/kernel/audit.h
index 6aa33b8..a337023 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -104,6 +104,7 @@ static inline int audit_hash_ino(u32 ino
return (ino & (AUDIT_INODE_BUCKETS-1));
}
+extern int audit_match_class(int class, unsigned syscall);
extern int audit_comparator(const u32 left, const u32 op, const u32 right);
extern int audit_compare_dname_path(const char *dname, const char *path,
int *dirlen);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 6a9a5c5..e1f7fce 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -302,6 +302,15 @@ int __init audit_register_class(int clas
return 0;
}
+int audit_match_class(int class, unsigned syscall)
+{
+ if (unlikely(syscall >= AUDIT_BITMASK_SIZE * sizeof(__u32)))
+ return 0;
+ if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class]))
+ return 0;
+ return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall);
+}
+
/* Common user-space to kernel rule translation. */
static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
{
@@ -413,6 +422,10 @@ static struct audit_entry *audit_rule_to
case AUDIT_ARG2:
case AUDIT_ARG3:
break;
+ case AUDIT_PERM:
+ if (f->val & ~15)
+ goto exit_free;
+ break;
case AUDIT_INODE:
err = audit_to_inode(&entry->rule, f);
if (err)
@@ -567,6 +580,10 @@ static struct audit_entry *audit_data_to
entry->rule.buflen += f->val;
entry->rule.filterkey = str;
break;
+ case AUDIT_PERM:
+ if (f->val & ~15)
+ goto exit_free;
+ break;
default:
goto exit_free;
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index efc1b74..7a83d80 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -209,6 +209,40 @@ #if AUDIT_DEBUG
#endif
};
+#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
+static int audit_match_perm(struct audit_context *ctx, int mask)
+{
+ unsigned n = ctx->major;
+ switch (audit_classify_syscall(ctx->arch, n)) {
+ case 0: /* native */
+ if ((mask & 2) && audit_match_class(AUDIT_CLASS_WRITE, n))
+ return 1;
+ if ((mask & 4) && audit_match_class(AUDIT_CLASS_READ, n))
+ return 1;
+ if ((mask & 8) && audit_match_class(AUDIT_CLASS_CHATTR, n))
+ return 1;
+ return 0;
+ case 1: /* 32bit on biarch */
+ if ((mask & 2) && audit_match_class(AUDIT_CLASS_WRITE_32, n))
+ return 1;
+ if ((mask & 4) && audit_match_class(AUDIT_CLASS_READ_32, n))
+ return 1;
+ if ((mask & 8) && audit_match_class(AUDIT_CLASS_CHATTR_32, n))
+ return 1;
+ return 0;
+ case 2: /* open */
+ return mask & ACC_MODE(ctx->argv[1]);
+ case 3: /* openat */
+ return mask & ACC_MODE(ctx->argv[2]);
+ case 4: /* socketcall */
+ return ((mask & 2) && ctx->argv[0] == SYS_BIND);
+ case 5: /* execve */
+ return mask & 1;
+ default:
+ return 0;
+ }
+}
+
/* Determine if any context name data matches a rule's watch data */
/* Compare a task_struct with an audit_rule. Return 1 on match, 0
* otherwise. */
@@ -397,6 +431,9 @@ static int audit_filter_rules(struct tas
/* ignore this field for filtering */
result = 1;
break;
+ case AUDIT_PERM:
+ result = audit_match_perm(ctx, f->val);
+ break;
}
if (!result)
18 years, 4 months
Adding multiple watch rules on same path
by Loulwa Salem
Hi Steve,
As I was running some of our watch tests, I noticed the following:
You can add multiple watches on the same path if you specify different filter
key values. That doesn't make sense to me, so I wanted to check if that is an
intended behavior? and if so why?
Also, since you can have multiple watches on same path, it is no longer
sufficient to do a "-W <path>" to remove the watch, now you have to specify
which watch to remove by using the "-k key" as well.
Is this is how auditctl will remain to function, because we need to make changes
to our functions accordingly
I am on the latest rawhide kernel(2.6.17-1.2573.fc6) and audit-1.2.5-8
[root~]# auditctl -w /tmp/file2
[root~]# auditctl -l
LIST_RULES: exit,always watch=/tmp/file2
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
[root~]# auditctl -w /tmp/file2 -k first-key
[root~]# auditctl -l
LIST_RULES: exit,always watch=/tmp/file2 key=first-key
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
LIST_RULES: exit,always watch=/tmp/file2
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
[root~]# auditctl -w /tmp/file2 -k second-key
[root~]# auditctl -l
LIST_RULES: exit,always watch=/tmp/file2 key=first-key
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
LIST_RULES: exit,always watch=/tmp/file2 key=second-key
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
LIST_RULES: exit,always watch=/tmp/file2
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
[root~]# auditctl -W /tmp/file2
[root~]# auditctl -l
LIST_RULES: exit,always watch=/tmp/file2 key=first-key
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
LIST_RULES: exit,always watch=/tmp/file2 key=second-key
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
[root~]# auditctl -W /tmp/file2
Error sending delete rule request (No rule matches)
[root~]# auditctl -l
LIST_RULES: exit,always watch=/tmp/file2 key=first-key
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
LIST_RULES: exit,always watch=/tmp/file2 key=second-key
syscall=open,truncate,ftruncate,rename,mkdir,rmdir,creat,link,unlink,symlink,
chmod,fchmod,chown,fchown,lchown
-Loulwa
18 years, 4 months
[PATCH] audit syscall classes
by Alexander Viro
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(a)zeniv.linux.org.uk>
---
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
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 5e70c2f..cbc1184 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -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
diff --git a/arch/i386/kernel/audit.c b/arch/i386/kernel/audit.c
new file mode 100644
index 0000000..5a53c6f
--- /dev/null
+++ b/arch/i386/kernel/audit.c
@@ -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);
diff --git a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile
index 61cb60a..baad8c7 100644
--- a/arch/ia64/ia32/Makefile
+++ b/arch/ia64/ia32/Makefile
@@ -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.
diff --git a/arch/ia64/ia32/audit.c b/arch/ia64/ia32/audit.c
new file mode 100644
index 0000000..ab94f2e
--- /dev/null
+++ b/arch/ia64/ia32/audit.c
@@ -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
+};
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 09a0dbc..0e4553f 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -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.
diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c
new file mode 100644
index 0000000..f251293
--- /dev/null
+++ b/arch/ia64/kernel/audit.c
@@ -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);
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile
index e9263b4..62bc5f5 100644
--- a/arch/x86_64/ia32/Makefile
+++ b/arch/x86_64/ia32/Makefile
@@ -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)
diff --git a/arch/x86_64/ia32/audit.c b/arch/x86_64/ia32/audit.c
new file mode 100644
index 0000000..ab94f2e
--- /dev/null
+++ b/arch/x86_64/ia32/audit.c
@@ -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
+};
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index aeb9c56..819e84e 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -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
diff --git a/arch/x86_64/kernel/audit.c b/arch/x86_64/kernel/audit.c
new file mode 100644
index 0000000..a067aa4
--- /dev/null
+++ b/arch/x86_64/kernel/audit.c
@@ -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);
diff --git a/include/asm-generic/audit_change_attr.h b/include/asm-generic/audit_change_attr.h
new file mode 100644
index 0000000..cb05bf6
--- /dev/null
+++ b/include/asm-generic/audit_change_attr.h
@@ -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
diff --git a/include/asm-generic/audit_dir_write.h b/include/asm-generic/audit_dir_write.h
new file mode 100644
index 0000000..161a7a5
--- /dev/null
+++ b/include/asm-generic/audit_dir_write.h
@@ -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,
diff --git a/include/linux/audit.h b/include/linux/audit.h
index c211f0a..b27d7de 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -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 */
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 7f2ea8b..5b4e162 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -279,6 +279,29 @@ static int audit_to_watch(struct audit_k
return 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 @@ #endif
for (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:
--
1.3.GIT
18 years, 4 months
ELF: what should be part of the userspace headers?
by Adrian Bunk
I'm currently a bit lost trying to understand what from the following
headers is part of the kernel <-> userspace ABI:
include/asm/elf.h
include/linux/elfcore.h
include/linux/elf-em.h
include/linux/elf-fdpic.h
include/linux/elf.h
include/linux/elf-em.h is used by include/linux/audit.h, but this usage
doesn't seem to be part of the kernel <-> userspace interface?
And which part of the ELF headers is part of the kernel <-> userspace
interface?
TIA
Adrian
--
Gentoo kernels are 42 times more popular than SUSE kernels among
KLive users (a service by SUSE contractor Andrea Arcangeli that
gathers data about kernels from many users worldwide).
There are three kinds of lies: Lies, Damn Lies, and Statistics.
Benjamin Disraeli
18 years, 4 months
SuSE 10.1 and linux audit
by Clif Flynt
Hi,
Here's the steps I've gone through for making the audit package work
with SuSE 10.1. If someone wants to point out some really bad things
I've done, feel free. I suspect that I've cut some corners that aren't
safe, but this seems to work.
This is a kludgey way to get things done, but it's working for now,
and these steps might help other folks do a better job of getting SuSE
10.1 and the audit utilities to play well together.
My hope is that by the time I need to go live with the site,
there will be an out-of-the-box solution to the problems.
I'm using stock 10.1, with the online updates, and Audit 1.2.5.
I install from the downloadable CD-ROM set.
1) Base install with C/C++ Development, and kernel development.
Do the online update as part of the install. (Is there an easy
way to get a snapshot of the updates as an ISO?)
2) Install 2.6.17.6 kernel source. I got the tarball from:
http://linux.softpedia.com/progDownload/Linux-Kernel-Download-1960.html
Untar, remove the old 'linux' link and create a new symlink
to the new kernel directory.
3) make oldconfig;
Take all defaults.
4) edit arch/i386/Makefile,
set FDINITRD flag = 1
There's probably a better way to do this, but this worked. It
wasn't necessary 2 weeks ago, and may not be necessary in the future,
but without that flag the kernel gets built but no initrd is
constructed, and the kernel won't boot.
5) Build and install kernel;
make; make modules; make install; make modules_install
6) Reboot to new kernel.
7) Install swig and python-devel using Yast2
8) Install the new kernel headers. I got these from:
http://rpm.pbone.net/index.php3/stat/26/dist/0/size/728548/name/glibc-ker...
I extracted the tar bz2 file with rpm2cpio, and then untarred
that file to install the headers.
This is one step that I think is very suspect. I'm not sure where these
headers are referenced, and which code is using what.
I've tried building the 2.6.17 kernel with both the original headers
and the new ones and seen no difference in behavior, but I might have
just not done a test that would exercise the trouble spots.
9) Extract the audit 1.2.5 code.
10) Rebuild the configure script, configure make and install.
I follow the cut/paste instructions in README-install
autoreconf -fv --install, etc.
11) Edit /etc/init.d/auditd
Remove the -n flag that's added for AUDITD_DISABLE_CONTEXTS"
under the start case. I don't think the -n option
is supported in 1.2.5, and when it's there, the output messages
go to /var/log/messages instead of /var/log/audit/audit.log.
Add
/sbin/auditctl -D
to the stop method. This gets rid of
an interminable set of messages to the screen during halt.
This is another thing that I think is suspect. Can a halt
be aborted once it's reached the K15auditd stage of shutdown?
If so, this is a security hole that would allow an unprivileged
user to disable auditing, if not, then it should be fine.
12) Install my audit.rules - I'm using all of the -a rules from
the sample capp.rules set.
13) create /etc/audit and copy /etc/auditd.conf and audit.rules
to it. Again, I think this step could be avoided by proper
use of various compile time flags, but this works.
--
.... Clif Flynt ... http://www.cflynt.com ... clif(a)cflynt.com ...
.. Tcl/Tk: A Developer's Guide (2nd edition) - Morgan Kauffman ..
..13th Annual Tcl/Tk Conference: Oct 9-13, 2006, Chicago, IL ..
............. http://www.tcl.tk/community/tcl2006/ ............
18 years, 4 months
issue with file watches on Suse 10.1 using latest 2.6.18-rc4 and audit 1.2.3
by Rick Warner
Hello all,
I am trying to set up file watches for files such as /etc/passwd
and /etc/shadow. I am using Suse 10.1. I have updated the kernel to a
kernel.org 2.6.18-rc4 kernel, and have updated the audit userspace tools to
version 1.2.3. I can add filesystem watches with "auditctl -w /etc/passwd"
successfully now. Entries in the audit.log are created.
The first problem is that when I use "aureport -w", it tells me "<no events of
interest were found>". Using "aureport -f" instead, it shows entries
for /etc/passwd, but the auid column for all results is -1 (or "unset" if
using the -i option to aureport). Looking at the audit logfile,
auid=4294967295 which then correlates to -1 when used as a signed vs unsigned
int.
How can I fix this?
--
Richard Warner
Lead Systems Integrator
Microway, Inc
(508)732-5517
18 years, 4 months