Merge git://git.infradead.org/users/eparis/audit
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 19 Oct 2014 23:25:56 +0000 (16:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 19 Oct 2014 23:25:56 +0000 (16:25 -0700)
Pull audit updates from Eric Paris:
 "So this change across a whole bunch of arches really solves one basic
  problem.  We want to audit when seccomp is killing a process.  seccomp
  hooks in before the audit syscall entry code.  audit_syscall_entry
  took as an argument the arch of the given syscall.  Since the arch is
  part of what makes a syscall number meaningful it's an important part
  of the record, but it isn't available when seccomp shoots the
  syscall...

  For most arch's we have a better way to get the arch (syscall_get_arch)
  So the solution was two fold: Implement syscall_get_arch() everywhere
  there is audit which didn't have it.  Use syscall_get_arch() in the
  seccomp audit code.  Having syscall_get_arch() everywhere meant it was
  a useless flag on the stack and we could get rid of it for the typical
  syscall entry.

  The other changes inside the audit system aren't grand, fixed some
  records that had invalid spaces.  Better locking around the task comm
  field.  Removing some dead functions and structs.  Make some things
  static.  Really minor stuff"

* git://git.infradead.org/users/eparis/audit: (31 commits)
  audit: rename audit_log_remove_rule to disambiguate for trees
  audit: cull redundancy in audit_rule_change
  audit: WARN if audit_rule_change called illegally
  audit: put rule existence check in canonical order
  next: openrisc: Fix build
  audit: get comm using lock to avoid race in string printing
  audit: remove open_arg() function that is never used
  audit: correct AUDIT_GET_FEATURE return message type
  audit: set nlmsg_len for multicast messages.
  audit: use union for audit_field values since they are mutually exclusive
  audit: invalid op= values for rules
  audit: use atomic_t to simplify audit_serial()
  kernel/audit.c: use ARRAY_SIZE instead of sizeof/sizeof[0]
  audit: reduce scope of audit_log_fcaps
  audit: reduce scope of audit_net_id
  audit: arm64: Remove the audit arch argument to audit_syscall_entry
  arm64: audit: Add audit hook in syscall_trace_enter/exit()
  audit: x86: drop arch from __audit_syscall_entry() interface
  sparc: implement is_32bit_task
  sparc: properly conditionalize use of TIF_32BIT
  ...

43 files changed:
arch/alpha/include/asm/syscall.h [new file with mode: 0644]
arch/alpha/kernel/ptrace.c
arch/arm/kernel/ptrace.c
arch/arm64/kernel/ptrace.c
arch/ia64/include/asm/syscall.h
arch/ia64/kernel/ptrace.c
arch/microblaze/include/asm/syscall.h
arch/microblaze/kernel/ptrace.c
arch/mips/include/asm/syscall.h
arch/mips/kernel/ptrace.c
arch/openrisc/include/asm/syscall.h
arch/openrisc/include/uapi/asm/elf.h
arch/openrisc/kernel/ptrace.c
arch/parisc/include/asm/syscall.h
arch/parisc/kernel/ptrace.c
arch/powerpc/include/asm/syscall.h
arch/powerpc/kernel/ptrace.c
arch/s390/kernel/ptrace.c
arch/sh/include/asm/syscall_32.h
arch/sh/include/asm/syscall_64.h
arch/sh/kernel/ptrace_32.c
arch/sh/kernel/ptrace_64.c
arch/sparc/include/asm/syscall.h
arch/sparc/include/asm/thread_info_32.h
arch/sparc/include/asm/thread_info_64.h
arch/sparc/kernel/ptrace_64.c
arch/um/kernel/ptrace.c
arch/x86/ia32/ia32entry.S
arch/x86/kernel/entry_32.S
arch/x86/kernel/ptrace.c
arch/x86/um/asm/ptrace.h
arch/x86/um/asm/syscall.h [new file with mode: 0644]
arch/xtensa/kernel/ptrace.c
include/asm-generic/syscall.h
include/linux/audit.h
include/uapi/linux/audit.h
include/uapi/linux/elf-em.h
kernel/audit.c
kernel/audit.h
kernel/audit_tree.c
kernel/audit_watch.c
kernel/auditfilter.c
kernel/auditsc.c

diff --git a/arch/alpha/include/asm/syscall.h b/arch/alpha/include/asm/syscall.h
new file mode 100644 (file)
index 0000000..88d28eb
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _ASM_ALPHA_SYSCALL_H
+#define _ASM_ALPHA_SYSCALL_H
+
+#include <uapi/linux/audit.h>
+
+static inline int syscall_get_arch(void)
+{
+       return AUDIT_ARCH_ALPHA;
+}
+
+#endif /* _ASM_ALPHA_SYSCALL_H */
index 86d8351..d9ee817 100644 (file)
@@ -321,7 +321,7 @@ asmlinkage unsigned long syscall_trace_enter(void)
        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
            tracehook_report_syscall_entry(current_pt_regs()))
                ret = -1UL;
-       audit_syscall_entry(AUDIT_ARCH_ALPHA, regs->r0, regs->r16, regs->r17, regs->r18, regs->r19);
+       audit_syscall_entry(regs->r0, regs->r16, regs->r17, regs->r18, regs->r19);
        return ret ?: current_pt_regs()->r0;
 }
 
index 5e772a2..ef9119f 100644 (file)
@@ -949,8 +949,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
        if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
                trace_sys_enter(regs, scno);
 
-       audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
-                           regs->ARM_r2, regs->ARM_r3);
+       audit_syscall_entry(scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2,
+                           regs->ARM_r3);
 
        return scno;
 }
index fe63ac5..8a4ae8e 100644 (file)
@@ -1120,8 +1120,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
        if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
                trace_sys_enter(regs, regs->syscallno);
 
-       audit_syscall_entry(syscall_get_arch(), regs->syscallno,
-               regs->orig_x0, regs->regs[1], regs->regs[2], regs->regs[3]);
+       audit_syscall_entry(regs->syscallno, regs->orig_x0, regs->regs[1],
+                           regs->regs[2], regs->regs[3]);
 
        return regs->syscallno;
 }
index a7ff1c6..1d0b875 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef _ASM_SYSCALL_H
 #define _ASM_SYSCALL_H 1
 
+#include <uapi/linux/audit.h>
 #include <linux/sched.h>
 #include <linux/err.h>
 
@@ -79,4 +80,9 @@ static inline void syscall_set_arguments(struct task_struct *task,
 
        ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
 }
+
+static inline int syscall_get_arch(void)
+{
+       return AUDIT_ARCH_IA64;
+}
 #endif /* _ASM_SYSCALL_H */
index b7a5fff..6f54d51 100644 (file)
@@ -1219,7 +1219,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
                ia64_sync_krbs();
 
 
-       audit_syscall_entry(AUDIT_ARCH_IA64, regs.r15, arg0, arg1, arg2, arg3);
+       audit_syscall_entry(regs.r15, arg0, arg1, arg2, arg3);
 
        return 0;
 }
index 9bc4317..53cfaf3 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ASM_MICROBLAZE_SYSCALL_H
 #define __ASM_MICROBLAZE_SYSCALL_H
 
+#include <uapi/linux/audit.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/ptrace.h>
@@ -99,4 +100,8 @@ static inline void syscall_set_arguments(struct task_struct *task,
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
 asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
 
+static inline int syscall_get_arch(void)
+{
+       return AUDIT_ARCH_MICROBLAZE;
+}
 #endif /* __ASM_MICROBLAZE_SYSCALL_H */
index 39cf508..bb10637 100644 (file)
@@ -147,8 +147,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
                 */
                ret = -1L;
 
-       audit_syscall_entry(EM_MICROBLAZE, regs->r12, regs->r5, regs->r6,
-                           regs->r7, regs->r8);
+       audit_syscall_entry(regs->r12, regs->r5, regs->r6, regs->r7, regs->r8);
 
        return ret ?: regs->r12;
 }
index cdf68b3..bb79637 100644 (file)
@@ -129,7 +129,7 @@ extern const unsigned long sysn32_call_table[];
 
 static inline int syscall_get_arch(void)
 {
-       int arch = EM_MIPS;
+       int arch = AUDIT_ARCH_MIPS;
 #ifdef CONFIG_64BIT
        if (!test_thread_flag(TIF_32BIT_REGS)) {
                arch |= __AUDIT_ARCH_64BIT;
index f7aac5b..9d1487d 100644 (file)
@@ -780,9 +780,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->regs[2]);
 
-       audit_syscall_entry(syscall_get_arch(),
-                           syscall,
-                           regs->regs[4], regs->regs[5],
+       audit_syscall_entry(syscall, regs->regs[4], regs->regs[5],
                            regs->regs[6], regs->regs[7]);
        return syscall;
 }
index b752bb6..2db9f1c 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef __ASM_OPENRISC_SYSCALL_H__
 #define __ASM_OPENRISC_SYSCALL_H__
 
+#include <uapi/linux/audit.h>
 #include <linux/err.h>
 #include <linux/sched.h>
 
@@ -71,4 +72,8 @@ syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
        memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
 }
 
+static inline int syscall_get_arch(void)
+{
+       return AUDIT_ARCH_OPENRISC;
+}
 #endif
index f02ea58..8884276 100644 (file)
@@ -55,9 +55,8 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 /* A placeholder; OR32 does not have fp support yes, so no fp regs for now.  */
 typedef unsigned long elf_fpregset_t;
 
-/* This should be moved to include/linux/elf.h */
+/* EM_OPENRISC is defined in linux/elf-em.h */
 #define EM_OR32         0x8472
-#define EM_OPENRISC     92     /* OpenRISC 32-bit embedded processor */
 
 /*
  * These are used to set parameters in the core dumps.
index 71a2a0c..4f59fa4 100644 (file)
@@ -187,8 +187,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
                 */
                ret = -1L;
 
-       audit_syscall_entry(AUDIT_ARCH_OPENRISC, regs->gpr[11],
-                           regs->gpr[3], regs->gpr[4],
+       audit_syscall_entry(regs->gpr[11], regs->gpr[3], regs->gpr[4],
                            regs->gpr[5], regs->gpr[6]);
 
        return ret ? : regs->gpr[11];
index 8bdfd2c..a5eba95 100644 (file)
@@ -3,6 +3,8 @@
 #ifndef _ASM_PARISC_SYSCALL_H_
 #define _ASM_PARISC_SYSCALL_H_
 
+#include <uapi/linux/audit.h>
+#include <linux/compat.h>
 #include <linux/err.h>
 #include <asm/ptrace.h>
 
@@ -37,4 +39,13 @@ static inline void syscall_get_arguments(struct task_struct *tsk,
        }
 }
 
+static inline int syscall_get_arch(void)
+{
+       int arch = AUDIT_ARCH_PARISC;
+#ifdef CONFIG_64BIT
+       if (!is_compat_task())
+               arch = AUDIT_ARCH_PARISC64;
+#endif
+       return arch;
+}
 #endif /*_ASM_PARISC_SYSCALL_H_*/
index 92438c2..9585c81 100644 (file)
@@ -280,14 +280,11 @@ long do_syscall_trace_enter(struct pt_regs *regs)
 
 #ifdef CONFIG_64BIT
        if (!is_compat_task())
-               audit_syscall_entry(AUDIT_ARCH_PARISC64,
-                       regs->gr[20],
-                       regs->gr[26], regs->gr[25],
-                       regs->gr[24], regs->gr[23]);
+               audit_syscall_entry(regs->gr[20], regs->gr[26], regs->gr[25],
+                                   regs->gr[24], regs->gr[23]);
        else
 #endif
-               audit_syscall_entry(AUDIT_ARCH_PARISC,
-                       regs->gr[20] & 0xffffffff,
+               audit_syscall_entry(regs->gr[20] & 0xffffffff,
                        regs->gr[26] & 0xffffffff,
                        regs->gr[25] & 0xffffffff,
                        regs->gr[24] & 0xffffffff,
index b54b2ad..6fa2708 100644 (file)
@@ -13,7 +13,9 @@
 #ifndef _ASM_SYSCALL_H
 #define _ASM_SYSCALL_H 1
 
+#include <uapi/linux/audit.h>
 #include <linux/sched.h>
+#include <linux/thread_info.h>
 
 /* ftrace syscalls requires exporting the sys_call_table */
 #ifdef CONFIG_FTRACE_SYSCALLS
@@ -86,4 +88,8 @@ static inline void syscall_set_arguments(struct task_struct *task,
        memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
 }
 
+static inline int syscall_get_arch(void)
+{
+       return is_32bit_task() ? AUDIT_ARCH_PPC : AUDIT_ARCH_PPC64;
+}
 #endif /* _ASM_SYSCALL_H */
index cdb404e..f21897b 100644 (file)
@@ -1788,14 +1788,11 @@ long do_syscall_trace_enter(struct pt_regs *regs)
 
 #ifdef CONFIG_PPC64
        if (!is_32bit_task())
-               audit_syscall_entry(AUDIT_ARCH_PPC64,
-                                   regs->gpr[0],
-                                   regs->gpr[3], regs->gpr[4],
+               audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4],
                                    regs->gpr[5], regs->gpr[6]);
        else
 #endif
-               audit_syscall_entry(AUDIT_ARCH_PPC,
-                                   regs->gpr[0],
+               audit_syscall_entry(regs->gpr[0],
                                    regs->gpr[3] & 0xffffffff,
                                    regs->gpr[4] & 0xffffffff,
                                    regs->gpr[5] & 0xffffffff,
index f537e93..99a567b 100644 (file)
@@ -834,9 +834,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->gprs[2]);
 
-       audit_syscall_entry(is_compat_task() ?
-                               AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
-                           regs->gprs[2], regs->orig_gpr2,
+       audit_syscall_entry(regs->gprs[2], regs->orig_gpr2,
                            regs->gprs[3], regs->gprs[4],
                            regs->gprs[5]);
 out:
index 7d80df4..95be3b0 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ASM_SH_SYSCALL_32_H
 #define __ASM_SH_SYSCALL_32_H
 
+#include <uapi/linux/audit.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/err.h>
@@ -93,4 +94,13 @@ static inline void syscall_set_arguments(struct task_struct *task,
        }
 }
 
+static inline int syscall_get_arch(void)
+{
+       int arch = AUDIT_ARCH_SH;
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       arch |= __AUDIT_ARCH_LE;
+#endif
+       return arch;
+}
 #endif /* __ASM_SH_SYSCALL_32_H */
index c3561ca..c6a797b 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ASM_SH_SYSCALL_64_H
 #define __ASM_SH_SYSCALL_64_H
 
+#include <uapi/linux/audit.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/ptrace.h>
@@ -61,4 +62,17 @@ static inline void syscall_set_arguments(struct task_struct *task,
        memcpy(&regs->regs[2 + i], args, n * sizeof(args[0]));
 }
 
+static inline int syscall_get_arch(void)
+{
+       int arch = AUDIT_ARCH_SH;
+
+#ifdef CONFIG_64BIT
+       arch |= __AUDIT_ARCH_64BIT;
+#endif
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       arch |= __AUDIT_ARCH_LE;
+#endif
+
+       return arch;
+}
 #endif /* __ASM_SH_SYSCALL_64_H */
index 668c816..c1a6b89 100644 (file)
@@ -484,17 +484,6 @@ long arch_ptrace(struct task_struct *child, long request,
        return ret;
 }
 
-static inline int audit_arch(void)
-{
-       int arch = EM_SH;
-
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-       arch |= __AUDIT_ARCH_LE;
-#endif
-
-       return arch;
-}
-
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
        long ret = 0;
@@ -513,8 +502,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->regs[0]);
 
-       audit_syscall_entry(audit_arch(), regs->regs[3],
-                           regs->regs[4], regs->regs[5],
+       audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5],
                            regs->regs[6], regs->regs[7]);
 
        return ret ?: regs->regs[0];
index af90339..5cea973 100644 (file)
@@ -504,20 +504,6 @@ asmlinkage int sh64_ptrace(long request, long pid,
        return sys_ptrace(request, pid, addr, data);
 }
 
-static inline int audit_arch(void)
-{
-       int arch = EM_SH;
-
-#ifdef CONFIG_64BIT
-       arch |= __AUDIT_ARCH_64BIT;
-#endif
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-       arch |= __AUDIT_ARCH_LE;
-#endif
-
-       return arch;
-}
-
 asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
 {
        long long ret = 0;
@@ -536,8 +522,7 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->regs[9]);
 
-       audit_syscall_entry(audit_arch(), regs->regs[1],
-                           regs->regs[2], regs->regs[3],
+       audit_syscall_entry(regs->regs[1], regs->regs[2], regs->regs[3],
                            regs->regs[4], regs->regs[5]);
 
        return ret ?: regs->regs[9];
index 025a02a..49f71fd 100644 (file)
@@ -1,9 +1,11 @@
 #ifndef __ASM_SPARC_SYSCALL_H
 #define __ASM_SPARC_SYSCALL_H
 
+#include <uapi/linux/audit.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/ptrace.h>
+#include <asm/thread_info.h>
 
 /*
  * The syscall table always contains 32 bit pointers since we know that the
@@ -124,4 +126,9 @@ static inline void syscall_set_arguments(struct task_struct *task,
                regs->u_regs[UREG_I0 + i + j] = args[j];
 }
 
+static inline int syscall_get_arch(void)
+{
+       return is_32bit_task() ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64;
+}
+
 #endif /* __ASM_SPARC_SYSCALL_H */
index 96efa7a..025c984 100644 (file)
@@ -130,6 +130,8 @@ register struct thread_info *current_thread_info_reg asm("g6");
 #define _TIF_DO_NOTIFY_RESUME_MASK     (_TIF_NOTIFY_RESUME | \
                                         _TIF_SIGPENDING)
 
+#define is_32bit_task()        (1)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
index cc6275c..798f027 100644 (file)
@@ -221,6 +221,8 @@ register struct thread_info *current_thread_info_reg asm("g6");
                                 _TIF_NEED_RESCHED)
 #define _TIF_DO_NOTIFY_RESUME_MASK     (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING)
 
+#define is_32bit_task()        (test_thread_flag(TIF_32BIT))
+
 /*
  * Thread-synchronous status.
  *
index c13c9f2..9ddc492 100644 (file)
@@ -1076,13 +1076,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->u_regs[UREG_G1]);
 
-       audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
-                            AUDIT_ARCH_SPARC :
-                            AUDIT_ARCH_SPARC64),
-                           regs->u_regs[UREG_G1],
-                           regs->u_regs[UREG_I0],
-                           regs->u_regs[UREG_I1],
-                           regs->u_regs[UREG_I2],
+       audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0],
+                           regs->u_regs[UREG_I1], regs->u_regs[UREG_I2],
                            regs->u_regs[UREG_I3]);
 
        return ret;
index 694d551..62435ef 100644 (file)
@@ -165,8 +165,7 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
  */
 void syscall_trace_enter(struct pt_regs *regs)
 {
-       audit_syscall_entry(HOST_AUDIT_ARCH,
-                           UPT_SYSCALL_NR(&regs->regs),
+       audit_syscall_entry(UPT_SYSCALL_NR(&regs->regs),
                            UPT_SYSCALL_ARG1(&regs->regs),
                            UPT_SYSCALL_ARG2(&regs->regs),
                            UPT_SYSCALL_ARG3(&regs->regs),
index 711de08..8ffba18 100644 (file)
@@ -198,12 +198,12 @@ sysexit_from_sys_call:
 
 #ifdef CONFIG_AUDITSYSCALL
        .macro auditsys_entry_common
-       movl %esi,%r9d                  /* 6th arg: 4th syscall arg */
-       movl %edx,%r8d                  /* 5th arg: 3rd syscall arg */
-       /* (already in %ecx)               4th arg: 2nd syscall arg */
-       movl %ebx,%edx                  /* 3rd arg: 1st syscall arg */
-       movl %eax,%esi                  /* 2nd arg: syscall number */
-       movl $AUDIT_ARCH_I386,%edi      /* 1st arg: audit arch */
+       movl %esi,%r8d                  /* 5th arg: 4th syscall arg */
+       movl %ecx,%r9d                  /*swap with edx*/
+       movl %edx,%ecx                  /* 4th arg: 3rd syscall arg */
+       movl %r9d,%edx                  /* 3rd arg: 2nd syscall arg */
+       movl %ebx,%esi                  /* 2nd arg: 1st syscall arg */
+       movl %eax,%edi                  /* 1st arg: syscall number */
        call __audit_syscall_entry
        movl RAX-ARGOFFSET(%rsp),%eax   /* reload syscall number */
        cmpq $(IA32_NR_syscalls-1),%rax
index 4b0e1df..b553ed8 100644 (file)
@@ -449,12 +449,11 @@ sysenter_audit:
        jnz syscall_trace_entry
        addl $4,%esp
        CFI_ADJUST_CFA_OFFSET -4
-       /* %esi already in 8(%esp)         6th arg: 4th syscall arg */
-       /* %edx already in 4(%esp)         5th arg: 3rd syscall arg */
-       /* %ecx already in 0(%esp)         4th arg: 2nd syscall arg */
-       movl %ebx,%ecx                  /* 3rd arg: 1st syscall arg */
-       movl %eax,%edx                  /* 2nd arg: syscall number */
-       movl $AUDIT_ARCH_I386,%eax      /* 1st arg: audit arch */
+       movl %esi,4(%esp)               /* 5th arg: 4th syscall arg */
+       movl %edx,(%esp)                /* 4th arg: 3rd syscall arg */
+       /* %ecx already in %ecx            3rd arg: 2nd syscall arg */
+       movl %ebx,%edx                  /* 2nd arg: 1st syscall arg */
+       /* %eax already in %eax            1st arg: syscall number */
        call __audit_syscall_entry
        pushl_cfi %ebx
        movl PT_EAX(%esp),%eax          /* reload syscall number */
index 29576c2..749b0e4 100644 (file)
@@ -1445,12 +1445,12 @@ static void do_audit_syscall_entry(struct pt_regs *regs, u32 arch)
 {
 #ifdef CONFIG_X86_64
        if (arch == AUDIT_ARCH_X86_64) {
-               audit_syscall_entry(arch, regs->orig_ax, regs->di,
+               audit_syscall_entry(regs->orig_ax, regs->di,
                                    regs->si, regs->dx, regs->r10);
        } else
 #endif
        {
-               audit_syscall_entry(arch, regs->orig_ax, regs->bx,
+               audit_syscall_entry(regs->orig_ax, regs->bx,
                                    regs->cx, regs->dx, regs->si);
        }
 }
index 54f8102..e59eef2 100644 (file)
@@ -47,8 +47,6 @@ struct user_desc;
 
 #ifdef CONFIG_X86_32
 
-#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
-
 extern int ptrace_get_thread_area(struct task_struct *child, int idx,
                                   struct user_desc __user *user_desc);
 
@@ -57,8 +55,6 @@ extern int ptrace_set_thread_area(struct task_struct *child, int idx,
 
 #else
 
-#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
-
 #define PT_REGS_R8(r) UPT_R8(&(r)->regs)
 #define PT_REGS_R9(r) UPT_R9(&(r)->regs)
 #define PT_REGS_R10(r) UPT_R10(&(r)->regs)
diff --git a/arch/x86/um/asm/syscall.h b/arch/x86/um/asm/syscall.h
new file mode 100644 (file)
index 0000000..9fe77b7
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __UM_ASM_SYSCALL_H
+#define __UM_ASM_SYSCALL_H
+
+#include <uapi/linux/audit.h>
+
+static inline int syscall_get_arch(void)
+{
+#ifdef CONFIG_X86_32
+       return AUDIT_ARCH_I386;
+#else
+       return AUDIT_ARCH_X86_64;
+#endif
+}
+
+#endif /* __UM_ASM_SYSCALL_H */
index 562fac6..4d54b48 100644 (file)
@@ -342,7 +342,7 @@ void do_syscall_trace_enter(struct pt_regs *regs)
                do_syscall_trace();
 
 #if 0
-       audit_syscall_entry(current, AUDIT_ARCH_XTENSA..);
+       audit_syscall_entry(...);
 #endif
 }
 
index d401e54..0c938a4 100644 (file)
@@ -147,7 +147,7 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
  *
  * Returns the AUDIT_ARCH_* based on the system call convention in use.
  *
- * It's only valid to call this when @task is stopped on entry to a system
+ * It's only valid to call this when current is stopped on entry to a system
  * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP.
  *
  * Architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must
index 22cfddb..36dffec 100644 (file)
@@ -66,12 +66,16 @@ struct audit_krule {
 
 struct audit_field {
        u32                             type;
-       u32                             val;
-       kuid_t                          uid;
-       kgid_t                          gid;
+       union {
+               u32                     val;
+               kuid_t                  uid;
+               kgid_t                  gid;
+               struct {
+                       char            *lsm_str;
+                       void            *lsm_rule;
+               };
+       };
        u32                             op;
-       char                            *lsm_str;
-       void                            *lsm_rule;
 };
 
 extern int is_audit_feature_set(int which);
@@ -109,12 +113,13 @@ extern void audit_log_session_info(struct audit_buffer *ab);
 #endif
 
 #ifdef CONFIG_AUDITSYSCALL
+#include <asm/syscall.h> /* for syscall_get_arch() */
+
 /* These are defined in auditsc.c */
                                /* Public API */
 extern int  audit_alloc(struct task_struct *task);
 extern void __audit_free(struct task_struct *task);
-extern void __audit_syscall_entry(int arch,
-                                 int major, unsigned long a0, unsigned long a1,
+extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1,
                                  unsigned long a2, unsigned long a3);
 extern void __audit_syscall_exit(int ret_success, long ret_value);
 extern struct filename *__audit_reusename(const __user char *uptr);
@@ -141,12 +146,12 @@ static inline void audit_free(struct task_struct *task)
        if (unlikely(task->audit_context))
                __audit_free(task);
 }
-static inline void audit_syscall_entry(int arch, int major, unsigned long a0,
+static inline void audit_syscall_entry(int major, unsigned long a0,
                                       unsigned long a1, unsigned long a2,
                                       unsigned long a3)
 {
        if (unlikely(current->audit_context))
-               __audit_syscall_entry(arch, major, a0, a1, a2, a3);
+               __audit_syscall_entry(major, a0, a1, a2, a3);
 }
 static inline void audit_syscall_exit(void *pt_regs)
 {
@@ -322,7 +327,7 @@ static inline int audit_alloc(struct task_struct *task)
 }
 static inline void audit_free(struct task_struct *task)
 { }
-static inline void audit_syscall_entry(int arch, int major, unsigned long a0,
+static inline void audit_syscall_entry(int major, unsigned long a0,
                                       unsigned long a1, unsigned long a2,
                                       unsigned long a3)
 { }
index 3b9ff33..d4dbef1 100644 (file)
@@ -352,6 +352,7 @@ enum {
 #define AUDIT_ARCH_IA64                (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_M32R                (EM_M32R)
 #define AUDIT_ARCH_M68K                (EM_68K)
+#define AUDIT_ARCH_MICROBLAZE  (EM_MICROBLAZE)
 #define AUDIT_ARCH_MIPS                (EM_MIPS)
 #define AUDIT_ARCH_MIPSEL      (EM_MIPS|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_MIPS64      (EM_MIPS|__AUDIT_ARCH_64BIT)
@@ -445,17 +446,4 @@ struct audit_rule_data {
        char            buf[0]; /* string fields buffer */
 };
 
-/* audit_rule is supported to maintain backward compatibility with
- * userspace.  It supports integer fields only and corresponds to
- * AUDIT_ADD, AUDIT_DEL and AUDIT_LIST requests.
- */
-struct audit_rule {            /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
-       __u32           flags;  /* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
-       __u32           action; /* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
-       __u32           field_count;
-       __u32           mask[AUDIT_BITMASK_SIZE];
-       __u32           fields[AUDIT_MAX_FIELDS];
-       __u32           values[AUDIT_MAX_FIELDS];
-};
-
 #endif /* _UAPI_LINUX_AUDIT_H_ */
index 01529bd..aa90bc9 100644 (file)
@@ -32,6 +32,7 @@
 #define EM_V850                87      /* NEC v850 */
 #define EM_M32R                88      /* Renesas M32R */
 #define EM_MN10300     89      /* Panasonic/MEI MN10300, AM33 */
+#define EM_OPENRISC     92     /* OpenRISC 32-bit embedded processor */
 #define EM_BLACKFIN     106     /* ADI Blackfin Processor */
 #define EM_TI_C6000    140     /* TI C6X DSPs */
 #define EM_AARCH64     183     /* ARM 64 bit */
index ba2ff5a..80983df 100644 (file)
@@ -126,7 +126,7 @@ static atomic_t    audit_lost = ATOMIC_INIT(0);
 
 /* The netlink socket. */
 static struct sock *audit_sock;
-int audit_net_id;
+static int audit_net_id;
 
 /* Hash for inode-based rules */
 struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
@@ -724,7 +724,7 @@ static int audit_get_feature(struct sk_buff *skb)
 
        seq = nlmsg_hdr(skb)->nlmsg_seq;
 
-       audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af));
+       audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af));
 
        return 0;
 }
@@ -750,7 +750,7 @@ static int audit_set_feature(struct sk_buff *skb)
        struct audit_features *uaf;
        int i;
 
-       BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > sizeof(audit_feature_names)/sizeof(audit_feature_names[0]));
+       BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names));
        uaf = nlmsg_data(nlmsg_hdr(skb));
 
        /* if there is ever a version 2 we should handle that here */
@@ -1301,19 +1301,9 @@ err:
  */
 unsigned int audit_serial(void)
 {
-       static DEFINE_SPINLOCK(serial_lock);
-       static unsigned int serial = 0;
+       static atomic_t serial = ATOMIC_INIT(0);
 
-       unsigned long flags;
-       unsigned int ret;
-
-       spin_lock_irqsave(&serial_lock, flags);
-       do {
-               ret = ++serial;
-       } while (unlikely(!ret));
-       spin_unlock_irqrestore(&serial_lock, flags);
-
-       return ret;
+       return atomic_add_return(1, &serial);
 }
 
 static inline void audit_get_stamp(struct audit_context *ctx,
@@ -1681,7 +1671,7 @@ void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap)
        }
 }
 
-void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
+static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
 {
        kernel_cap_t *perm = &name->fcap.permitted;
        kernel_cap_t *inh = &name->fcap.inheritable;
@@ -1860,7 +1850,7 @@ EXPORT_SYMBOL(audit_log_task_context);
 void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
 {
        const struct cred *cred;
-       char name[sizeof(tsk->comm)];
+       char comm[sizeof(tsk->comm)];
        struct mm_struct *mm = tsk->mm;
        char *tty;
 
@@ -1894,9 +1884,8 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
                         from_kgid(&init_user_ns, cred->fsgid),
                         tty, audit_get_sessionid(tsk));
 
-       get_task_comm(name, tsk);
        audit_log_format(ab, " comm=");
-       audit_log_untrustedstring(ab, name);
+       audit_log_untrustedstring(ab, get_task_comm(comm, tsk));
 
        if (mm) {
                down_read(&mm->mmap_sem);
@@ -1959,6 +1948,7 @@ void audit_log_end(struct audit_buffer *ab)
        } else {
                struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
 
+               nlh->nlmsg_len = ab->skb->len;
                kauditd_send_multicast_skb(ab->skb);
 
                /*
@@ -1970,7 +1960,7 @@ void audit_log_end(struct audit_buffer *ab)
                 * protocol between the kaudit kernel subsystem and the auditd
                 * userspace code.
                 */
-               nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
+               nlh->nlmsg_len -= NLMSG_HDRLEN;
 
                if (audit_pid) {
                        skb_queue_tail(&audit_skb_queue, ab->skb);
index 7bb6573..3cdffad 100644 (file)
@@ -222,7 +222,6 @@ extern void audit_copy_inode(struct audit_names *name,
                             const struct inode *inode);
 extern void audit_log_cap(struct audit_buffer *ab, char *prefix,
                          kernel_cap_t *cap);
-extern void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name);
 extern void audit_log_name(struct audit_context *context,
                           struct audit_names *n, struct path *path,
                           int record_num, int *call_panic);
index 135944a..e242e3a 100644 (file)
@@ -449,7 +449,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
        return 0;
 }
 
-static void audit_log_remove_rule(struct audit_krule *rule)
+static void audit_tree_log_remove_rule(struct audit_krule *rule)
 {
        struct audit_buffer *ab;
 
@@ -457,7 +457,7 @@ static void audit_log_remove_rule(struct audit_krule *rule)
        if (unlikely(!ab))
                return;
        audit_log_format(ab, "op=");
-       audit_log_string(ab, "remove rule");
+       audit_log_string(ab, "remove_rule");
        audit_log_format(ab, " dir=");
        audit_log_untrustedstring(ab, rule->tree->pathname);
        audit_log_key(ab, rule->filterkey);
@@ -476,7 +476,7 @@ static void kill_rules(struct audit_tree *tree)
                list_del_init(&rule->rlist);
                if (rule->tree) {
                        /* not a half-baked one */
-                       audit_log_remove_rule(rule);
+                       audit_tree_log_remove_rule(rule);
                        rule->tree = NULL;
                        list_del_rcu(&entry->list);
                        list_del(&entry->rule.list);
index 70b4554..ad9c168 100644 (file)
@@ -314,7 +314,7 @@ static void audit_update_watch(struct audit_parent *parent,
                                             &nentry->rule.list);
                        }
 
-                       audit_watch_log_rule_change(r, owatch, "updated rules");
+                       audit_watch_log_rule_change(r, owatch, "updated_rules");
 
                        call_rcu(&oentry->rcu, audit_free_rule_rcu);
                }
@@ -342,7 +342,7 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
        list_for_each_entry_safe(w, nextw, &parent->watches, wlist) {
                list_for_each_entry_safe(r, nextr, &w->rules, rlist) {
                        e = container_of(r, struct audit_entry, rule);
-                       audit_watch_log_rule_change(r, w, "remove rule");
+                       audit_watch_log_rule_change(r, w, "remove_rule");
                        list_del(&r->rlist);
                        list_del(&r->list);
                        list_del_rcu(&e->list);
index c447cd9..3598e13 100644 (file)
@@ -71,6 +71,24 @@ static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {
 
 DEFINE_MUTEX(audit_filter_mutex);
 
+static void audit_free_lsm_field(struct audit_field *f)
+{
+       switch (f->type) {
+       case AUDIT_SUBJ_USER:
+       case AUDIT_SUBJ_ROLE:
+       case AUDIT_SUBJ_TYPE:
+       case AUDIT_SUBJ_SEN:
+       case AUDIT_SUBJ_CLR:
+       case AUDIT_OBJ_USER:
+       case AUDIT_OBJ_ROLE:
+       case AUDIT_OBJ_TYPE:
+       case AUDIT_OBJ_LEV_LOW:
+       case AUDIT_OBJ_LEV_HIGH:
+               kfree(f->lsm_str);
+               security_audit_rule_free(f->lsm_rule);
+       }
+}
+
 static inline void audit_free_rule(struct audit_entry *e)
 {
        int i;
@@ -80,11 +98,8 @@ static inline void audit_free_rule(struct audit_entry *e)
        if (erule->watch)
                audit_put_watch(erule->watch);
        if (erule->fields)
-               for (i = 0; i < erule->field_count; i++) {
-                       struct audit_field *f = &erule->fields[i];
-                       kfree(f->lsm_str);
-                       security_audit_rule_free(f->lsm_rule);
-               }
+               for (i = 0; i < erule->field_count; i++)
+                       audit_free_lsm_field(&erule->fields[i]);
        kfree(erule->fields);
        kfree(erule->filterkey);
        kfree(e);
@@ -148,7 +163,7 @@ static inline int audit_to_inode(struct audit_krule *krule,
                                 struct audit_field *f)
 {
        if (krule->listnr != AUDIT_FILTER_EXIT ||
-           krule->watch || krule->inode_f || krule->tree ||
+           krule->inode_f || krule->watch || krule->tree ||
            (f->op != Audit_equal && f->op != Audit_not_equal))
                return -EINVAL;
 
@@ -422,10 +437,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
 
                f->type = data->fields[i];
                f->val = data->values[i];
-               f->uid = INVALID_UID;
-               f->gid = INVALID_GID;
-               f->lsm_str = NULL;
-               f->lsm_rule = NULL;
 
                /* Support legacy tests for a valid loginuid */
                if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) {
@@ -1053,30 +1064,27 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data,
        int err = 0;
        struct audit_entry *entry;
 
+       entry = audit_data_to_entry(data, datasz);
+       if (IS_ERR(entry))
+               return PTR_ERR(entry);
+
        switch (type) {
        case AUDIT_ADD_RULE:
-               entry = audit_data_to_entry(data, datasz);
-               if (IS_ERR(entry))
-                       return PTR_ERR(entry);
-
                err = audit_add_rule(entry);
-               audit_log_rule_change("add rule", &entry->rule, !err);
-               if (err)
-                       audit_free_rule(entry);
+               audit_log_rule_change("add_rule", &entry->rule, !err);
                break;
        case AUDIT_DEL_RULE:
-               entry = audit_data_to_entry(data, datasz);
-               if (IS_ERR(entry))
-                       return PTR_ERR(entry);
-
                err = audit_del_rule(entry);
-               audit_log_rule_change("remove rule", &entry->rule, !err);
-               audit_free_rule(entry);
+               audit_log_rule_change("remove_rule", &entry->rule, !err);
                break;
        default:
-               return -EINVAL;
+               err = -EINVAL;
+               WARN_ON(1);
        }
 
+       if (err || type == AUDIT_DEL_RULE)
+               audit_free_rule(entry);
+
        return err;
 }
 
index 7208c1d..e420a0c 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/binfmts.h>
 #include <linux/highmem.h>
 #include <linux/syscalls.h>
+#include <asm/syscall.h>
 #include <linux/capability.h>
 #include <linux/fs_struct.h>
 #include <linux/compat.h>
@@ -125,14 +126,6 @@ struct audit_tree_refs {
        struct audit_chunk *c[31];
 };
 
-static inline int open_arg(int flags, int mask)
-{
-       int n = ACC_MODE(flags);
-       if (flags & (O_TRUNC | O_CREAT))
-               n |= AUDIT_PERM_WRITE;
-       return n & mask;
-}
-
 static int audit_match_perm(struct audit_context *ctx, int mask)
 {
        unsigned n;
@@ -1505,7 +1498,6 @@ void __audit_free(struct task_struct *tsk)
 
 /**
  * audit_syscall_entry - fill in an audit record at syscall entry
- * @arch: architecture type
  * @major: major syscall type (function)
  * @a1: additional syscall register 1
  * @a2: additional syscall register 2
@@ -1520,9 +1512,8 @@ void __audit_free(struct task_struct *tsk)
  * will only be written if another part of the kernel requests that it
  * be written).
  */
-void __audit_syscall_entry(int arch, int major,
-                        unsigned long a1, unsigned long a2,
-                        unsigned long a3, unsigned long a4)
+void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,
+                          unsigned long a3, unsigned long a4)
 {
        struct task_struct *tsk = current;
        struct audit_context *context = tsk->audit_context;
@@ -1536,7 +1527,7 @@ void __audit_syscall_entry(int arch, int major,
        if (!audit_enabled)
                return;
 
-       context->arch       = arch;
+       context->arch       = syscall_get_arch();
        context->major      = major;
        context->argv[0]    = a1;
        context->argv[1]    = a2;
@@ -2433,6 +2424,7 @@ static void audit_log_task(struct audit_buffer *ab)
        kgid_t gid;
        unsigned int sessionid;
        struct mm_struct *mm = current->mm;
+       char comm[sizeof(current->comm)];
 
        auid = audit_get_loginuid(current);
        sessionid = audit_get_sessionid(current);
@@ -2445,7 +2437,7 @@ static void audit_log_task(struct audit_buffer *ab)
                         sessionid);
        audit_log_task_context(ab);
        audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
-       audit_log_untrustedstring(ab, current->comm);
+       audit_log_untrustedstring(ab, get_task_comm(comm, current));
        if (mm) {
                down_read(&mm->mmap_sem);
                if (mm->exe_file)
@@ -2488,11 +2480,9 @@ void __audit_seccomp(unsigned long syscall, long signr, int code)
        if (unlikely(!ab))
                return;
        audit_log_task(ab);
-       audit_log_format(ab, " sig=%ld", signr);
-       audit_log_format(ab, " syscall=%ld", syscall);
-       audit_log_format(ab, " compat=%d", is_compat_task());
-       audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current));
-       audit_log_format(ab, " code=0x%x", code);
+       audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x",
+                        signr, syscall_get_arch(), syscall, is_compat_task(),
+                        KSTK_EIP(current), code);
        audit_log_end(ab);
 }