[PATCH] per arch syscall info

Chris Wright chrisw at osdl.org
Thu Mar 17 02:13:41 UTC 2005


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(&regs))
+		int arch;
+		if (IS_IA32_PROCESS(&regs)) {
 			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(&regs) ? 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;
-------------- next part --------------
--- audit-0.6.8/lib/lookup_table.c~orig	2005-03-15 16:17:54.000000000 -0800
+++ audit-0.6.8/lib/lookup_table.c	2005-03-15 16:18:36.000000000 -0800
@@ -51,6 +51,7 @@ static struct transtab fieldtab[] = {
     { AUDIT_FSGID,    "fsgid"    },
     { AUDIT_LOGINUID, "loginuid" },
     { AUDIT_PERS,     "pers"     },
+    { AUDIT_ARCH,     "arch"     },
 
     { AUDIT_DEVMAJOR, "devmajor" },
     { AUDIT_DEVMINOR, "devminor" },
--- audit-0.6.8/lib/libaudit.h~orig	2005-03-15 16:48:38.000000000 -0800
+++ audit-0.6.8/lib/libaudit.h	2005-03-15 16:49:02.000000000 -0800
@@ -34,6 +34,7 @@
 /* TODO: Add this as a kernel patch to audit.h */
 /* These audit message types are for audit daemon local use. */
 #define AUDIT_DAEMON	1500     /* Define daemon local records */
+#define AUDIT_ARCH	11
 
 /* defines for audit subsystem */
 
--- audit-0.6.8/lib/libaudit.c~orig	2005-03-15 17:10:06.000000000 -0800
+++ audit-0.6.8/lib/libaudit.c	2005-03-15 17:10:57.000000000 -0800
@@ -399,8 +399,10 @@ int audit_rule_fieldpair(struct audit_ru
 
 	snprintf(buf, sizeof(buf), "%*.*s", v-f-negated, v-f-negated, f);
 	msg(LOG_DEBUG,"buf=%s\n", buf);
-	if ((field = audit_name_to_field(buf)) < 0) 
+	if ((field = audit_name_to_field(buf)) < 0) {
+		printf("bye\n");
 		return -2;
+	}
 	msg(LOG_DEBUG,"f%d%s%s\n", field, negated ? "!=" : "=", v+1);
 	rule->fields[rule->field_count] = field | (negated ? AUDIT_NEGATE : 0);
 	switch (field)


More information about the Linux-audit mailing list