Here's a real rough stab at per arch syscall info. I tested it very
briefly on x86_64 and ia64 with both native and ia32 binaries. It at
least spit out the arch values I expected, and I was able to filter by
arch as expected (with audit userspace patch attached).
thanks,
-chris
--
===== arch/ia64/kernel/ptrace.c 1.47 vs edited =====
--- 1.47/arch/ia64/kernel/ptrace.c 2005-03-13 15:29:47 -08:00
+++ edited/arch/ia64/kernel/ptrace.c 2005-03-16 17:25:17 -08:00
@@ -1598,12 +1598,16 @@ syscall_trace_enter (long arg0, long arg
long syscall;
if (unlikely(current->audit_context)) {
- if (IS_IA32_PROCESS(®s))
+ int arch;
+ if (IS_IA32_PROCESS(®s)) {
syscall = regs.r1;
- else
+ arch = AUDIT_ARCH_IA32;
+ } else {
syscall = regs.r15;
+ arch = AUDIT_ARCH_IA64;
+ }
- audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3);
+ audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3);
}
if (test_thread_flag(TIF_SYSCALL_TRACE)
@@ -1618,8 +1622,10 @@ syscall_trace_leave (long arg0, long arg
long arg4, long arg5, long arg6, long arg7,
struct pt_regs regs)
{
- if (unlikely(current->audit_context))
- audit_syscall_exit(current, regs.r8);
+ if (unlikely(current->audit_context)) {
+ int arch = IS_IA32_PROCESS(®s) ? AUDIT_ARCH_IA32 : AUDIT_ARCH_IA64;
+ audit_syscall_exit(current, arch, regs.r8);
+ }
if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED))
===== arch/x86_64/kernel/ptrace.c 1.21 vs edited =====
--- 1.21/arch/x86_64/kernel/ptrace.c 2005-03-07 20:41:40 -08:00
+++ edited/arch/x86_64/kernel/ptrace.c 2005-03-15 13:55:54 -08:00
@@ -520,13 +520,16 @@ static void syscall_trace(struct pt_regs
}
}
+#define audit_arch() \
+test_thread_flag(TIF_IA32) ? AUDIT_ARCH_IA32 : AUDIT_ARCH_X86_64
+
asmlinkage void syscall_trace_enter(struct pt_regs *regs)
{
/* do the secure computing check first */
secure_computing(regs->orig_rax);
if (unlikely(current->audit_context))
- audit_syscall_entry(current, regs->orig_rax,
+ audit_syscall_entry(current, audit_arch(), regs->orig_rax,
regs->rdi, regs->rsi,
regs->rdx, regs->r10);
@@ -537,8 +540,9 @@ asmlinkage void syscall_trace_enter(stru
asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{
- if (unlikely(current->audit_context))
- audit_syscall_exit(current, regs->rax);
+ if (unlikely(current->audit_context)) {
+ audit_syscall_exit(current, audit_arch(), regs->rax);
+ }
if ((test_thread_flag(TIF_SYSCALL_TRACE)
|| test_thread_flag(TIF_SINGLESTEP))
===== include/linux/audit.h 1.3 vs edited =====
--- 1.3/include/linux/audit.h 2005-03-11 12:32:31 -08:00
+++ edited/include/linux/audit.h 2005-03-15 13:50:26 -08:00
@@ -67,6 +67,7 @@
#define AUDIT_FSGID 8
#define AUDIT_LOGINUID 9
#define AUDIT_PERS 10
+#define AUDIT_ARCH 11
/* These are ONLY useful when checking
* at syscall exit time (AUDIT_AT_EXIT). */
@@ -96,6 +97,14 @@
#define AUDIT_FAIL_PRINTK 1
#define AUDIT_FAIL_PANIC 2
+/* distinguish syscall tables */
+#define AUDIT_ARCH_IA32 0
+#define AUDIT_ARCH_X86_64 1
+#define AUDIT_ARCH_IA64 2
+#define AUDIT_ARCH_PPC 3
+#define AUDIT_ARCH_PPC64 4
+#define AUDIT_ARCH_MIPS 5
+
#ifndef __KERNEL__
struct audit_message {
struct nlmsghdr nlh;
@@ -135,10 +144,10 @@ struct audit_context;
/* Public API */
extern int audit_alloc(struct task_struct *task);
extern void audit_free(struct task_struct *task);
-extern void audit_syscall_entry(struct task_struct *task,
+extern void audit_syscall_entry(struct task_struct *task, int table,
int major, unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3);
-extern void audit_syscall_exit(struct task_struct *task, int return_code);
+extern void audit_syscall_exit(struct task_struct *task, int table, int return_code);
extern void audit_getname(const char *name);
extern void audit_putname(const char *name);
extern void audit_inode(const char *name, unsigned long ino, dev_t rdev);
@@ -153,8 +162,8 @@ extern uid_t audit_get_loginuid(struct a
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
-#define audit_syscall_entry(t,a,b,c,d,e) do { ; } while (0)
-#define audit_syscall_exit(t,r) do { ; } while (0)
+#define audit_syscall_entry(t,ta,a,b,c,d,e) do { ; } while (0)
+#define audit_syscall_exit(t,ta,r) do { ; } while (0)
#define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0)
#define audit_inode(n,i,d) do { ; } while (0)
===== kernel/auditsc.c 1.7 vs edited =====
--- 1.7/kernel/auditsc.c 2005-03-01 00:15:00 -08:00
+++ edited/kernel/auditsc.c 2005-03-15 17:41:51 -08:00
@@ -113,6 +113,7 @@ struct audit_context {
uid_t uid, euid, suid, fsuid;
gid_t gid, egid, sgid, fsgid;
unsigned long personality;
+ int arch;
#if AUDIT_DEBUG
int put_count;
@@ -326,6 +327,10 @@ static int audit_filter_rules(struct tas
case AUDIT_PERS:
result = (tsk->personality == value);
break;
+ case AUDIT_ARCH:
+ if (ctx)
+ result = (ctx->arch == value);
+ break;
case AUDIT_EXIT:
if (ctx && ctx->return_valid)
@@ -588,6 +593,7 @@ static void audit_log_exit(struct audit_
audit_log_format(ab, "syscall=%d", context->major);
if (context->personality != PER_LINUX)
audit_log_format(ab, " per=%lx", context->personality);
+ audit_log_format(ab, " arch=%d", context->arch);
if (context->return_valid)
audit_log_format(ab, " exit=%d", context->return_code);
audit_log_format(ab,
@@ -686,7 +692,7 @@ static inline unsigned int audit_serial(
* then the record will be written at syscall exit time (otherwise, it
* will only be written if another part of the kernel requests that it
* be written). */
-void audit_syscall_entry(struct task_struct *tsk, int major,
+void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4)
{
@@ -740,6 +746,7 @@ void audit_syscall_entry(struct task_str
if (!audit_enabled)
return;
+ context->arch = arch;
context->major = major;
context->argv[0] = a1;
context->argv[1] = a2;
@@ -763,7 +770,7 @@ void audit_syscall_entry(struct task_str
* filtering, or because some other part of the kernel write an audit
* message), then write out the syscall information. In call cases,
* free the names stored from getname(). */
-void audit_syscall_exit(struct task_struct *tsk, int return_code)
+void audit_syscall_exit(struct task_struct *tsk, int arch, int return_code)
{
struct audit_context *context;
@@ -782,6 +789,7 @@ void audit_syscall_exit(struct task_stru
context->in_syscall = 0;
context->auditable = 0;
+ context->arch = arch;
if (context->previous) {
struct audit_context *new_context = context->previous;
context->previous = NULL;