Merge git://git.infradead.org/users/eparis/audit
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 12 Apr 2014 19:38:53 +0000 (12:38 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 12 Apr 2014 19:38:53 +0000 (12:38 -0700)
Pull audit updates from Eric Paris.

* git://git.infradead.org/users/eparis/audit: (28 commits)
  AUDIT: make audit_is_compat depend on CONFIG_AUDIT_COMPAT_GENERIC
  audit: renumber AUDIT_FEATURE_CHANGE into the 1300 range
  audit: do not cast audit_rule_data pointers pointlesly
  AUDIT: Allow login in non-init namespaces
  audit: define audit_is_compat in kernel internal header
  kernel: Use RCU_INIT_POINTER(x, NULL) in audit.c
  sched: declare pid_alive as inline
  audit: use uapi/linux/audit.h for AUDIT_ARCH declarations
  syscall_get_arch: remove useless function arguments
  audit: remove stray newline from audit_log_execve_info() audit_panic() call
  audit: remove stray newlines from audit_log_lost messages
  audit: include subject in login records
  audit: remove superfluous new- prefix in AUDIT_LOGIN messages
  audit: allow user processes to log from another PID namespace
  audit: anchor all pid references in the initial pid namespace
  audit: convert PPIDs to the inital PID namespace.
  pid: get pid_t ppid of task in init_pid_ns
  audit: rename the misleading audit_get_context() to audit_take_context()
  audit: Add generic compat syscall support
  audit: Add CONFIG_HAVE_ARCH_AUDITSYSCALL
  ...

36 files changed:
arch/alpha/Kconfig
arch/arm/Kconfig
arch/arm/include/asm/syscall.h
arch/ia64/Kconfig
arch/mips/include/asm/syscall.h
arch/mips/kernel/ptrace.c
arch/parisc/Kconfig
arch/powerpc/Kconfig
arch/s390/Kconfig
arch/s390/include/asm/syscall.h
arch/sh/Kconfig
arch/sparc/Kconfig
arch/um/Kconfig.common
arch/x86/Kconfig
arch/x86/include/asm/syscall.h
drivers/tty/tty_audit.c
fs/proc/base.c
include/asm-generic/syscall.h
include/linux/audit.h
include/linux/mm.h
include/linux/sched.h
include/uapi/linux/audit.h
include/uapi/linux/capability.h
init/Kconfig
kernel/audit.c
kernel/audit.h
kernel/auditfilter.c
kernel/auditsc.c
kernel/seccomp.c
lib/Kconfig
lib/Makefile
lib/audit.c
lib/compat_audit.c [new file with mode: 0644]
mm/util.c
security/integrity/integrity_audit.c
security/lsm_audit.c

index f6c6b34..b7ff9a3 100644 (file)
@@ -22,6 +22,7 @@ config ALPHA
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
+       select HAVE_ARCH_AUDITSYSCALL
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
        select ODD_RT_SIGACTION
index 5db05f6..ab438cb 100644 (file)
@@ -24,6 +24,7 @@ config ARM
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
        select HARDIRQS_SW_RESEND
+       select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT)
        select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
index 73ddd72..4651f69 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef _ASM_ARM_SYSCALL_H
 #define _ASM_ARM_SYSCALL_H
 
-#include <linux/audit.h> /* for AUDIT_ARCH_* */
+#include <uapi/linux/audit.h> /* for AUDIT_ARCH_* */
 #include <linux/elf.h> /* for ELF_EM */
 #include <linux/err.h>
 #include <linux/sched.h>
@@ -103,8 +103,7 @@ static inline void syscall_set_arguments(struct task_struct *task,
        memcpy(&regs->ARM_r0 + i, args, n * sizeof(args[0]));
 }
 
-static inline int syscall_get_arch(struct task_struct *task,
-                                  struct pt_regs *regs)
+static inline int syscall_get_arch(void)
 {
        /* ARM tasks don't change audit architectures on the fly. */
        return AUDIT_ARCH_ARM;
index 1325c3b..12c3afe 100644 (file)
@@ -45,6 +45,7 @@ config IA64
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
        select ARCH_USE_CMPXCHG_LOCKREF
+       select HAVE_ARCH_AUDITSYSCALL
        default y
        help
          The Itanium Processor Family is Intel's 64-bit successor to
index 6c488c8..c6e9cd2 100644 (file)
@@ -14,7 +14,7 @@
 #define __ASM_MIPS_SYSCALL_H
 
 #include <linux/compiler.h>
-#include <linux/audit.h>
+#include <uapi/linux/audit.h>
 #include <linux/elf-em.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -127,12 +127,11 @@ extern const unsigned long sys_call_table[];
 extern const unsigned long sys32_call_table[];
 extern const unsigned long sysn32_call_table[];
 
-static inline int syscall_get_arch(struct task_struct *task,
-                                  struct pt_regs *regs)
+static inline int syscall_get_arch(void)
 {
        int arch = EM_MIPS;
 #ifdef CONFIG_64BIT
-       if (!test_tsk_thread_flag(task, TIF_32BIT_REGS))
+       if (!test_thread_flag(TIF_32BIT_REGS))
                arch |= __AUDIT_ARCH_64BIT;
 #endif
 #if defined(__LITTLE_ENDIAN)
index 7271e5a..71f85f4 100644 (file)
@@ -649,7 +649,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(current, regs),
+       audit_syscall_entry(syscall_get_arch(),
                            syscall,
                            regs->regs[4], regs->regs[5],
                            regs->regs[6], regs->regs[7]);
index bb2a8ec..1faefed 100644 (file)
@@ -28,6 +28,7 @@ config PARISC
        select CLONE_BACKWARDS
        select TTY # Needed for pdc_cons.c
        select HAVE_DEBUG_STACKOVERFLOW
+       select HAVE_ARCH_AUDITSYSCALL
 
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
index 6c03a94..e099899 100644 (file)
@@ -144,6 +144,7 @@ config PPC
        select HAVE_DEBUG_STACKOVERFLOW
        select HAVE_IRQ_EXIT_ON_IRQ_STACK
        select ARCH_USE_CMPXCHG_LOCKREF if PPC64
+       select HAVE_ARCH_AUDITSYSCALL
 
 config GENERIC_CSUM
        def_bool CPU_LITTLE_ENDIAN
index 346d216..d68fe34 100644 (file)
@@ -103,6 +103,7 @@ config S390
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_TIME_VSYSCALL
        select HAVE_ALIGNED_STRUCT_PAGE if SLUB
+       select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
index cd29d2f..7776870 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef _ASM_SYSCALL_H
 #define _ASM_SYSCALL_H 1
 
-#include <linux/audit.h>
+#include <uapi/linux/audit.h>
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <asm/ptrace.h>
@@ -89,11 +89,10 @@ static inline void syscall_set_arguments(struct task_struct *task,
                regs->orig_gpr2 = args[0];
 }
 
-static inline int syscall_get_arch(struct task_struct *task,
-                                  struct pt_regs *regs)
+static inline int syscall_get_arch(void)
 {
 #ifdef CONFIG_COMPAT
-       if (test_tsk_thread_flag(task, TIF_31BIT))
+       if (test_tsk_thread_flag(current, TIF_31BIT))
                return AUDIT_ARCH_S390;
 #endif
        return sizeof(long) == 8 ? AUDIT_ARCH_S390X : AUDIT_ARCH_S390;
index ba55e93..834b67c 100644 (file)
@@ -42,6 +42,7 @@ config SUPERH
        select MODULES_USE_ELF_RELA
        select OLD_SIGSUSPEND
        select OLD_SIGACTION
+       select HAVE_ARCH_AUDITSYSCALL
        help
          The SuperH is a RISC processor targeted for use in embedded systems
          and consumer electronics; it was also used in the Sega Dreamcast
index 7d8b7e9..29f2e98 100644 (file)
@@ -77,6 +77,7 @@ config SPARC64
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select HAVE_C_RECORDMCOUNT
        select NO_BOOTMEM
+       select HAVE_ARCH_AUDITSYSCALL
 
 config ARCH_DEFCONFIG
        string
index 21ca44c..6915d28 100644 (file)
@@ -1,6 +1,7 @@
 config UML
        bool
        default y
+       select HAVE_ARCH_AUDITSYSCALL
        select HAVE_UID16
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
index 5b8ec0f..25d2c6f 100644 (file)
@@ -129,6 +129,7 @@ config X86
        select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64
        select HAVE_CC_STACKPROTECTOR
        select GENERIC_CPU_AUTOPROBE
+       select HAVE_ARCH_AUDITSYSCALL
 
 config INSTRUCTION_DECODER
        def_bool y
index aea284b..d6a756a 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef _ASM_X86_SYSCALL_H
 #define _ASM_X86_SYSCALL_H
 
-#include <linux/audit.h>
+#include <uapi/linux/audit.h>
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <asm/asm-offsets.h>   /* For NR_syscalls */
@@ -91,8 +91,7 @@ static inline void syscall_set_arguments(struct task_struct *task,
        memcpy(&regs->bx + i, args, n * sizeof(args[0]));
 }
 
-static inline int syscall_get_arch(struct task_struct *task,
-                                  struct pt_regs *regs)
+static inline int syscall_get_arch(void)
 {
        return AUDIT_ARCH_I386;
 }
@@ -221,8 +220,7 @@ static inline void syscall_set_arguments(struct task_struct *task,
                }
 }
 
-static inline int syscall_get_arch(struct task_struct *task,
-                                  struct pt_regs *regs)
+static inline int syscall_get_arch(void)
 {
 #ifdef CONFIG_IA32_EMULATION
        /*
@@ -234,7 +232,7 @@ static inline int syscall_get_arch(struct task_struct *task,
         *
         * x32 tasks should be considered AUDIT_ARCH_X86_64.
         */
-       if (task_thread_info(task)->status & TS_COMPAT)
+       if (task_thread_info(current)->status & TS_COMPAT)
                return AUDIT_ARCH_I386;
 #endif
        /* Both x32 and x86_64 are considered "64-bit". */
index b0e5401..90ca082 100644 (file)
@@ -65,6 +65,7 @@ static void tty_audit_log(const char *description, int major, int minor,
 {
        struct audit_buffer *ab;
        struct task_struct *tsk = current;
+       pid_t pid = task_pid_nr(tsk);
        uid_t uid = from_kuid(&init_user_ns, task_uid(tsk));
        uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(tsk));
        unsigned int sessionid = audit_get_sessionid(tsk);
@@ -74,7 +75,7 @@ static void tty_audit_log(const char *description, int major, int minor,
                char name[sizeof(tsk->comm)];
 
                audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d"
-                                " minor=%d comm=", description, tsk->pid, uid,
+                                " minor=%d comm=", description, pid, uid,
                                 loginuid, sessionid, major, minor);
                get_task_comm(name, tsk);
                audit_log_untrustedstring(ab, name);
index 6b7087e..2d696b0 100644 (file)
@@ -200,41 +200,9 @@ static int proc_root_link(struct dentry *dentry, struct path *path)
        return result;
 }
 
-static int proc_pid_cmdline(struct task_struct *task, char * buffer)
+static int proc_pid_cmdline(struct task_struct *task, char *buffer)
 {
-       int res = 0;
-       unsigned int len;
-       struct mm_struct *mm = get_task_mm(task);
-       if (!mm)
-               goto out;
-       if (!mm->arg_end)
-               goto out_mm;    /* Shh! No looking before we're done */
-
-       len = mm->arg_end - mm->arg_start;
-       if (len > PAGE_SIZE)
-               len = PAGE_SIZE;
-       res = access_process_vm(task, mm->arg_start, buffer, len, 0);
-
-       // If the nul at the end of args has been overwritten, then
-       // assume application is using setproctitle(3).
-       if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
-               len = strnlen(buffer, res);
-               if (len < res) {
-                   res = len;
-               } else {
-                       len = mm->env_end - mm->env_start;
-                       if (len > PAGE_SIZE - res)
-                               len = PAGE_SIZE - res;
-                       res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
-                       res = strnlen(buffer, res);
-               }
-       }
-out_mm:
-       mmput(mm);
-out:
-       return res;
+       return get_cmdline(task, buffer, PAGE_SIZE);
 }
 
 static int proc_pid_auxv(struct task_struct *task, char *buffer)
index 5b09392..d401e54 100644 (file)
@@ -144,8 +144,6 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
 
 /**
  * syscall_get_arch - return the AUDIT_ARCH for the current system call
- * @task:      task of interest, must be in system call entry tracing
- * @regs:      task_pt_regs() of @task
  *
  * Returns the AUDIT_ARCH_* based on the system call convention in use.
  *
@@ -155,5 +153,5 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
  * Architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must
  * provide an implementation of this.
  */
-int syscall_get_arch(struct task_struct *task, struct pt_regs *regs);
+int syscall_get_arch(void);
 #endif /* _ASM_SYSCALL_H */
index ec1464d..22cfddb 100644 (file)
@@ -79,6 +79,14 @@ extern int is_audit_feature_set(int which);
 extern int __init audit_register_class(int class, unsigned *list);
 extern int audit_classify_syscall(int abi, unsigned syscall);
 extern int audit_classify_arch(int arch);
+/* only for compat system calls */
+extern unsigned compat_write_class[];
+extern unsigned compat_read_class[];
+extern unsigned compat_dir_class[];
+extern unsigned compat_chattr_class[];
+extern unsigned compat_signal_class[];
+
+extern int __weak audit_classify_compat_syscall(int abi, unsigned syscall);
 
 /* audit_names->type values */
 #define        AUDIT_TYPE_UNKNOWN      0       /* we don't know yet */
@@ -94,6 +102,12 @@ struct filename;
 
 extern void audit_log_session_info(struct audit_buffer *ab);
 
+#ifdef CONFIG_AUDIT_COMPAT_GENERIC
+#define audit_is_compat(arch)  (!((arch) & __AUDIT_ARCH_64BIT))
+#else
+#define audit_is_compat(arch)  false
+#endif
+
 #ifdef CONFIG_AUDITSYSCALL
 /* These are defined in auditsc.c */
                                /* Public API */
index abc8484..bf9811e 100644 (file)
@@ -1204,6 +1204,7 @@ void account_page_writeback(struct page *page);
 int set_page_dirty(struct page *page);
 int set_page_dirty_lock(struct page *page);
 int clear_page_dirty_for_io(struct page *page);
+int get_cmdline(struct task_struct *task, char *buffer, int buflen);
 
 /* Is the vma a continuation of the stack vma above it? */
 static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr)
index 075b305..25f54c7 100644 (file)
@@ -1719,6 +1719,24 @@ static inline pid_t task_tgid_vnr(struct task_struct *tsk)
 }
 
 
+static inline int pid_alive(const struct task_struct *p);
+static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
+{
+       pid_t pid = 0;
+
+       rcu_read_lock();
+       if (pid_alive(tsk))
+               pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
+       rcu_read_unlock();
+
+       return pid;
+}
+
+static inline pid_t task_ppid_nr(const struct task_struct *tsk)
+{
+       return task_ppid_nr_ns(tsk, &init_pid_ns);
+}
+
 static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk,
                                        struct pid_namespace *ns)
 {
@@ -1758,7 +1776,7 @@ static inline pid_t task_pgrp_nr(struct task_struct *tsk)
  *
  * Return: 1 if the process is alive. 0 otherwise.
  */
-static inline int pid_alive(struct task_struct *p)
+static inline int pid_alive(const struct task_struct *p)
 {
        return p->pids[PIDTYPE_PID].pid != NULL;
 }
index 2d48fe1..11917f7 100644 (file)
@@ -70,7 +70,6 @@
 #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */
 #define AUDIT_SET_FEATURE      1018    /* Turn an audit feature on or off */
 #define AUDIT_GET_FEATURE      1019    /* Get which features are enabled */
-#define AUDIT_FEATURE_CHANGE   1020    /* audit log listing feature changes */
 
 #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly uninteresting to kernel */
 #define AUDIT_USER_AVC         1107    /* We filter this differently */
 #define AUDIT_NETFILTER_PKT    1324    /* Packets traversing netfilter chains */
 #define AUDIT_NETFILTER_CFG    1325    /* Netfilter chain modifications */
 #define AUDIT_SECCOMP          1326    /* Secure Computing event */
+#define AUDIT_PROCTITLE                1327    /* Proctitle emit event */
+#define AUDIT_FEATURE_CHANGE   1328    /* audit log listing feature changes */
 
 #define AUDIT_AVC              1400    /* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR      1401    /* Internal SE Linux Errors */
index ba478fa..154dd6d 100644 (file)
@@ -308,8 +308,12 @@ struct vfs_cap_data {
 
 #define CAP_LEASE            28
 
+/* Allow writing the audit log via unicast netlink socket */
+
 #define CAP_AUDIT_WRITE      29
 
+/* Allow configuration of audit via unicast netlink socket */
+
 #define CAP_AUDIT_CONTROL    30
 
 #define CAP_SETFCAP         31
index 427ba60..765018c 100644 (file)
@@ -292,9 +292,12 @@ config AUDIT
          logging of avc messages output).  Does not do system-call
          auditing without CONFIG_AUDITSYSCALL.
 
+config HAVE_ARCH_AUDITSYSCALL
+       bool
+
 config AUDITSYSCALL
        bool "Enable system-call auditing support"
-       depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT) || ALPHA)
+       depends on AUDIT && HAVE_ARCH_AUDITSYSCALL
        default y if SECURITY_SELINUX
        help
          Enable low-overhead system-call auditing infrastructure that
index 95a20f3..7c28936 100644 (file)
@@ -182,7 +182,7 @@ struct audit_buffer {
 
 struct audit_reply {
        __u32 portid;
-       struct net *net;        
+       struct net *net;
        struct sk_buff *skb;
 };
 
@@ -396,7 +396,7 @@ static void audit_printk_skb(struct sk_buff *skb)
                if (printk_ratelimit())
                        pr_notice("type=%d %s\n", nlh->nlmsg_type, data);
                else
-                       audit_log_lost("printk limit exceeded\n");
+                       audit_log_lost("printk limit exceeded");
        }
 
        audit_hold_skb(skb);
@@ -412,7 +412,7 @@ static void kauditd_send_skb(struct sk_buff *skb)
                BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */
                if (audit_pid) {
                        pr_err("*NO* daemon at audit_pid=%d\n", audit_pid);
-                       audit_log_lost("auditd disappeared\n");
+                       audit_log_lost("auditd disappeared");
                        audit_pid = 0;
                        audit_sock = NULL;
                }
@@ -607,7 +607,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
 {
        int err = 0;
 
-       /* Only support the initial namespaces for now. */
+       /* Only support initial user namespace for now. */
        /*
         * We return ECONNREFUSED because it tricks userspace into thinking
         * that audit was not configured into the kernel.  Lots of users
@@ -618,8 +618,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
         * userspace will reject all logins.  This should be removed when we
         * support non init namespaces!!
         */
-       if ((current_user_ns() != &init_user_ns) ||
-           (task_active_pid_ns(current) != &init_pid_ns))
+       if (current_user_ns() != &init_user_ns)
                return -ECONNREFUSED;
 
        switch (msg_type) {
@@ -639,6 +638,11 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
        case AUDIT_TTY_SET:
        case AUDIT_TRIM:
        case AUDIT_MAKE_EQUIV:
+               /* Only support auditd and auditctl in initial pid namespace
+                * for now. */
+               if ((task_active_pid_ns(current) != &init_pid_ns))
+                       return -EPERM;
+
                if (!capable(CAP_AUDIT_CONTROL))
                        err = -EPERM;
                break;
@@ -659,6 +663,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
 {
        int rc = 0;
        uid_t uid = from_kuid(&init_user_ns, current_uid());
+       pid_t pid = task_tgid_nr(current);
 
        if (!audit_enabled && msg_type != AUDIT_USER_AVC) {
                *ab = NULL;
@@ -668,7 +673,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
        *ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
        if (unlikely(!*ab))
                return rc;
-       audit_log_format(*ab, "pid=%d uid=%u", task_tgid_vnr(current), uid);
+       audit_log_format(*ab, "pid=%d uid=%u", pid, uid);
        audit_log_session_info(*ab);
        audit_log_task_context(*ab);
 
@@ -1097,7 +1102,7 @@ static void __net_exit audit_net_exit(struct net *net)
                audit_sock = NULL;
        }
 
-       rcu_assign_pointer(aunet->nlsk, NULL);
+       RCU_INIT_POINTER(aunet->nlsk, NULL);
        synchronize_net();
        netlink_kernel_release(sock);
 }
@@ -1829,11 +1834,11 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
        spin_unlock_irq(&tsk->sighand->siglock);
 
        audit_log_format(ab,
-                        " ppid=%ld pid=%d auid=%u uid=%u gid=%u"
+                        " ppid=%d pid=%d auid=%u uid=%u gid=%u"
                         " euid=%u suid=%u fsuid=%u"
                         " egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
-                        sys_getppid(),
-                        tsk->pid,
+                        task_ppid_nr(tsk),
+                        task_pid_nr(tsk),
                         from_kuid(&init_user_ns, audit_get_loginuid(tsk)),
                         from_kuid(&init_user_ns, cred->uid),
                         from_kgid(&init_user_ns, cred->gid),
index 8df1322..7bb6573 100644 (file)
@@ -106,6 +106,11 @@ struct audit_names {
        bool                    should_free;
 };
 
+struct audit_proctitle {
+       int     len;    /* length of the cmdline field. */
+       char    *value; /* the cmdline field */
+};
+
 /* The per-task audit context. */
 struct audit_context {
        int                 dummy;      /* must be the first element */
@@ -202,6 +207,7 @@ struct audit_context {
                } execve;
        };
        int fds[2];
+       struct audit_proctitle proctitle;
 
 #if AUDIT_DEBUG
        int                 put_count;
index 92062fd..8e9bc9c 100644 (file)
@@ -19,6 +19,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/audit.h>
 #include <linux/kthread.h>
@@ -226,7 +228,7 @@ static int audit_match_signal(struct audit_entry *entry)
 #endif
 
 /* Common user-space to kernel rule translation. */
-static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
+static inline struct audit_entry *audit_to_entry_common(struct audit_rule_data *rule)
 {
        unsigned listnr;
        struct audit_entry *entry;
@@ -249,7 +251,7 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
                ;
        }
        if (unlikely(rule->action == AUDIT_POSSIBLE)) {
-               printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n");
+               pr_err("AUDIT_POSSIBLE is deprecated\n");
                goto exit_err;
        }
        if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS)
@@ -403,7 +405,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
        int i;
        char *str;
 
-       entry = audit_to_entry_common((struct audit_rule *)data);
+       entry = audit_to_entry_common(data);
        if (IS_ERR(entry))
                goto exit_nofree;
 
@@ -431,6 +433,19 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                        f->val = 0;
                }
 
+               if ((f->type == AUDIT_PID) || (f->type == AUDIT_PPID)) {
+                       struct pid *pid;
+                       rcu_read_lock();
+                       pid = find_vpid(f->val);
+                       if (!pid) {
+                               rcu_read_unlock();
+                               err = -ESRCH;
+                               goto exit_free;
+                       }
+                       f->val = pid_nr(pid);
+                       rcu_read_unlock();
+               }
+
                err = audit_field_valid(entry, f);
                if (err)
                        goto exit_free;
@@ -479,8 +494,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                        /* Keep currently invalid fields around in case they
                         * become valid after a policy reload. */
                        if (err == -EINVAL) {
-                               printk(KERN_WARNING "audit rule for LSM "
-                                      "\'%s\' is invalid\n",  str);
+                               pr_warn("audit rule for LSM \'%s\' is invalid\n",
+                                       str);
                                err = 0;
                        }
                        if (err) {
@@ -709,8 +724,8 @@ static inline int audit_dupe_lsm_field(struct audit_field *df,
        /* Keep currently invalid fields around in case they
         * become valid after a policy reload. */
        if (ret == -EINVAL) {
-               printk(KERN_WARNING "audit rule for LSM \'%s\' is "
-                      "invalid\n", df->lsm_str);
+               pr_warn("audit rule for LSM \'%s\' is invalid\n",
+                       df->lsm_str);
                ret = 0;
        }
 
@@ -1240,12 +1255,14 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type,
 
        for (i = 0; i < rule->field_count; i++) {
                struct audit_field *f = &rule->fields[i];
+               pid_t pid;
                int result = 0;
                u32 sid;
 
                switch (f->type) {
                case AUDIT_PID:
-                       result = audit_comparator(task_pid_vnr(current), f->op, f->val);
+                       pid = task_pid_nr(current);
+                       result = audit_comparator(pid, f->op, f->val);
                        break;
                case AUDIT_UID:
                        result = audit_uid_comparator(current_uid(), f->op, f->uid);
index 7aef2f4..f251a5e 100644 (file)
@@ -42,6 +42,8 @@
  * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <asm/types.h>
 #include <linux/atomic.h>
@@ -68,6 +70,7 @@
 #include <linux/capability.h>
 #include <linux/fs_struct.h>
 #include <linux/compat.h>
+#include <linux/ctype.h>
 
 #include "audit.h"
 
@@ -79,6 +82,9 @@
 /* no execve audit message should be longer than this (userspace limits) */
 #define MAX_EXECVE_AUDIT_LEN 7500
 
+/* max length to print of cmdline/proctitle value during audit */
+#define MAX_PROCTITLE_AUDIT_LEN 128
+
 /* number of audit rules */
 int audit_n_rules;
 
@@ -451,15 +457,17 @@ static int audit_filter_rules(struct task_struct *tsk,
                struct audit_field *f = &rule->fields[i];
                struct audit_names *n;
                int result = 0;
+               pid_t pid;
 
                switch (f->type) {
                case AUDIT_PID:
-                       result = audit_comparator(tsk->pid, f->op, f->val);
+                       pid = task_pid_nr(tsk);
+                       result = audit_comparator(pid, f->op, f->val);
                        break;
                case AUDIT_PPID:
                        if (ctx) {
                                if (!ctx->ppid)
-                                       ctx->ppid = sys_getppid();
+                                       ctx->ppid = task_ppid_nr(tsk);
                                result = audit_comparator(ctx->ppid, f->op, f->val);
                        }
                        break;
@@ -805,7 +813,8 @@ void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
        rcu_read_unlock();
 }
 
-static inline struct audit_context *audit_get_context(struct task_struct *tsk,
+/* Transfer the audit context pointer to the caller, clearing it in the tsk's struct */
+static inline struct audit_context *audit_take_context(struct task_struct *tsk,
                                                      int return_valid,
                                                      long return_code)
 {
@@ -842,6 +851,13 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
        return context;
 }
 
+static inline void audit_proctitle_free(struct audit_context *context)
+{
+       kfree(context->proctitle.value);
+       context->proctitle.value = NULL;
+       context->proctitle.len = 0;
+}
+
 static inline void audit_free_names(struct audit_context *context)
 {
        struct audit_names *n, *next;
@@ -850,16 +866,15 @@ static inline void audit_free_names(struct audit_context *context)
        if (context->put_count + context->ino_count != context->name_count) {
                int i = 0;
 
-               printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d"
-                      " name_count=%d put_count=%d"
-                      " ino_count=%d [NOT freeing]\n",
-                      __FILE__, __LINE__,
+               pr_err("%s:%d(:%d): major=%d in_syscall=%d"
+                      " name_count=%d put_count=%d ino_count=%d"
+                      " [NOT freeing]\n", __FILE__, __LINE__,
                       context->serial, context->major, context->in_syscall,
                       context->name_count, context->put_count,
                       context->ino_count);
                list_for_each_entry(n, &context->names_list, list) {
-                       printk(KERN_ERR "names[%d] = %p = %s\n", i++,
-                              n->name, n->name->name ?: "(null)");
+                       pr_err("names[%d] = %p = %s\n", i++, n->name,
+                              n->name->name ?: "(null)");
                }
                dump_stack();
                return;
@@ -955,6 +970,7 @@ static inline void audit_free_context(struct audit_context *context)
        audit_free_aux(context);
        kfree(context->filterkey);
        kfree(context->sockaddr);
+       audit_proctitle_free(context);
        kfree(context);
 }
 
@@ -1157,7 +1173,7 @@ static void audit_log_execve_info(struct audit_context *context,
         */
        buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
        if (!buf) {
-               audit_panic("out of memory for argv string\n");
+               audit_panic("out of memory for argv string");
                return;
        }
 
@@ -1271,6 +1287,59 @@ static void show_special(struct audit_context *context, int *call_panic)
        audit_log_end(ab);
 }
 
+static inline int audit_proctitle_rtrim(char *proctitle, int len)
+{
+       char *end = proctitle + len - 1;
+       while (end > proctitle && !isprint(*end))
+               end--;
+
+       /* catch the case where proctitle is only 1 non-print character */
+       len = end - proctitle + 1;
+       len -= isprint(proctitle[len-1]) == 0;
+       return len;
+}
+
+static void audit_log_proctitle(struct task_struct *tsk,
+                        struct audit_context *context)
+{
+       int res;
+       char *buf;
+       char *msg = "(null)";
+       int len = strlen(msg);
+       struct audit_buffer *ab;
+
+       ab = audit_log_start(context, GFP_KERNEL, AUDIT_PROCTITLE);
+       if (!ab)
+               return; /* audit_panic or being filtered */
+
+       audit_log_format(ab, "proctitle=");
+
+       /* Not  cached */
+       if (!context->proctitle.value) {
+               buf = kmalloc(MAX_PROCTITLE_AUDIT_LEN, GFP_KERNEL);
+               if (!buf)
+                       goto out;
+               /* Historically called this from procfs naming */
+               res = get_cmdline(tsk, buf, MAX_PROCTITLE_AUDIT_LEN);
+               if (res == 0) {
+                       kfree(buf);
+                       goto out;
+               }
+               res = audit_proctitle_rtrim(buf, res);
+               if (res == 0) {
+                       kfree(buf);
+                       goto out;
+               }
+               context->proctitle.value = buf;
+               context->proctitle.len = res;
+       }
+       msg = context->proctitle.value;
+       len = context->proctitle.len;
+out:
+       audit_log_n_untrustedstring(ab, msg, len);
+       audit_log_end(ab);
+}
+
 static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
 {
        int i, call_panic = 0;
@@ -1388,6 +1457,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                audit_log_name(context, n, NULL, i++, &call_panic);
        }
 
+       audit_log_proctitle(tsk, context);
+
        /* Send end of event record to help user space know we are finished */
        ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
        if (ab)
@@ -1406,7 +1477,7 @@ void __audit_free(struct task_struct *tsk)
 {
        struct audit_context *context;
 
-       context = audit_get_context(tsk, 0, 0);
+       context = audit_take_context(tsk, 0, 0);
        if (!context)
                return;
 
@@ -1500,7 +1571,7 @@ void __audit_syscall_exit(int success, long return_code)
        else
                success = AUDITSC_FAILURE;
 
-       context = audit_get_context(tsk, success, return_code);
+       context = audit_take_context(tsk, success, return_code);
        if (!context)
                return;
 
@@ -1550,7 +1621,7 @@ static inline void handle_one(const struct inode *inode)
        if (likely(put_tree_ref(context, chunk)))
                return;
        if (unlikely(!grow_tree_refs(context))) {
-               printk(KERN_WARNING "out of memory, audit has lost a tree reference\n");
+               pr_warn("out of memory, audit has lost a tree reference\n");
                audit_set_auditable(context);
                audit_put_chunk(chunk);
                unroll_tree_refs(context, p, count);
@@ -1609,8 +1680,7 @@ retry:
                        goto retry;
                }
                /* too bad */
-               printk(KERN_WARNING
-                       "out of memory, audit has lost a tree reference\n");
+               pr_warn("out of memory, audit has lost a tree reference\n");
                unroll_tree_refs(context, p, count);
                audit_set_auditable(context);
                return;
@@ -1682,7 +1752,7 @@ void __audit_getname(struct filename *name)
 
        if (!context->in_syscall) {
 #if AUDIT_DEBUG == 2
-               printk(KERN_ERR "%s:%d(:%d): ignoring getname(%p)\n",
+               pr_err("%s:%d(:%d): ignoring getname(%p)\n",
                       __FILE__, __LINE__, context->serial, name);
                dump_stack();
 #endif
@@ -1721,15 +1791,15 @@ void audit_putname(struct filename *name)
        BUG_ON(!context);
        if (!name->aname || !context->in_syscall) {
 #if AUDIT_DEBUG == 2
-               printk(KERN_ERR "%s:%d(:%d): final_putname(%p)\n",
+               pr_err("%s:%d(:%d): final_putname(%p)\n",
                       __FILE__, __LINE__, context->serial, name);
                if (context->name_count) {
                        struct audit_names *n;
                        int i = 0;
 
                        list_for_each_entry(n, &context->names_list, list)
-                               printk(KERN_ERR "name[%d] = %p = %s\n", i++,
-                                      n->name, n->name->name ?: "(null)");
+                               pr_err("name[%d] = %p = %s\n", i++, n->name,
+                                      n->name->name ?: "(null)");
                        }
 #endif
                final_putname(name);
@@ -1738,9 +1808,8 @@ void audit_putname(struct filename *name)
        else {
                ++context->put_count;
                if (context->put_count > context->name_count) {
-                       printk(KERN_ERR "%s:%d(:%d): major=%d"
-                              " in_syscall=%d putname(%p) name_count=%d"
-                              " put_count=%d\n",
+                       pr_err("%s:%d(:%d): major=%d in_syscall=%d putname(%p)"
+                              " name_count=%d put_count=%d\n",
                               __FILE__, __LINE__,
                               context->serial, context->major,
                               context->in_syscall, name->name,
@@ -1981,12 +2050,10 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
        ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
        if (!ab)
                return;
-       audit_log_format(ab, "pid=%d uid=%u"
-                        " old-auid=%u new-auid=%u old-ses=%u new-ses=%u"
-                        " res=%d",
-                        current->pid, uid,
-                        oldloginuid, loginuid, oldsessionid, sessionid,
-                        !rc);
+       audit_log_format(ab, "pid=%d uid=%u", task_pid_nr(current), uid);
+       audit_log_task_context(ab);
+       audit_log_format(ab, " old-auid=%u auid=%u old-ses=%u ses=%u res=%d",
+                        oldloginuid, loginuid, oldsessionid, sessionid, !rc);
        audit_log_end(ab);
 }
 
@@ -2208,7 +2275,7 @@ void __audit_ptrace(struct task_struct *t)
 {
        struct audit_context *context = current->audit_context;
 
-       context->target_pid = t->pid;
+       context->target_pid = task_pid_nr(t);
        context->target_auid = audit_get_loginuid(t);
        context->target_uid = task_uid(t);
        context->target_sessionid = audit_get_sessionid(t);
@@ -2233,7 +2300,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
 
        if (audit_pid && t->tgid == audit_pid) {
                if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
-                       audit_sig_pid = tsk->pid;
+                       audit_sig_pid = task_pid_nr(tsk);
                        if (uid_valid(tsk->loginuid))
                                audit_sig_uid = tsk->loginuid;
                        else
@@ -2247,7 +2314,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
        /* optimize the common case by putting first signal recipient directly
         * in audit_context */
        if (!ctx->target_pid) {
-               ctx->target_pid = t->tgid;
+               ctx->target_pid = task_tgid_nr(t);
                ctx->target_auid = audit_get_loginuid(t);
                ctx->target_uid = t_uid;
                ctx->target_sessionid = audit_get_sessionid(t);
@@ -2268,7 +2335,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
        }
        BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
 
-       axp->target_pid[axp->pid_count] = t->tgid;
+       axp->target_pid[axp->pid_count] = task_tgid_nr(t);
        axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
        axp->target_uid[axp->pid_count] = t_uid;
        axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
@@ -2368,7 +2435,7 @@ static void audit_log_task(struct audit_buffer *ab)
                         from_kgid(&init_user_ns, gid),
                         sessionid);
        audit_log_task_context(ab);
-       audit_log_format(ab, " pid=%d comm=", current->pid);
+       audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
        audit_log_untrustedstring(ab, current->comm);
        if (mm) {
                down_read(&mm->mmap_sem);
index fd609bd..d8d046c 100644 (file)
@@ -71,7 +71,7 @@ static void populate_seccomp_data(struct seccomp_data *sd)
        struct pt_regs *regs = task_pt_regs(task);
 
        sd->nr = syscall_get_nr(task, regs);
-       sd->arch = syscall_get_arch(task, regs);
+       sd->arch = syscall_get_arch();
 
        /* Unroll syscall_get_args to help gcc on arm. */
        syscall_get_arguments(task, regs, 0, 1, (unsigned long *) &sd->args[0]);
@@ -348,7 +348,7 @@ static void seccomp_send_sigsys(int syscall, int reason)
        info.si_code = SYS_SECCOMP;
        info.si_call_addr = (void __user *)KSTK_EIP(current);
        info.si_errno = reason;
-       info.si_arch = syscall_get_arch(current, task_pt_regs(current));
+       info.si_arch = syscall_get_arch();
        info.si_syscall = syscall;
        force_sig_info(SIGSYS, &info, current);
 }
index 5d4984c..4771fb3 100644 (file)
@@ -182,6 +182,15 @@ config AUDIT_GENERIC
        depends on AUDIT && !AUDIT_ARCH
        default y
 
+config AUDIT_ARCH_COMPAT_GENERIC
+       bool
+       default n
+
+config AUDIT_COMPAT_GENERIC
+       bool
+       depends on AUDIT_GENERIC && AUDIT_ARCH_COMPAT_GENERIC && COMPAT
+       default y
+
 config RANDOM32_SELFTEST
        bool "PRNG perform self test on init"
        default n
index 48140e3..0cd7b68 100644 (file)
@@ -96,6 +96,7 @@ obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
 obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
 obj-$(CONFIG_SMP) += percpu_counter.o
 obj-$(CONFIG_AUDIT_GENERIC) += audit.o
+obj-$(CONFIG_AUDIT_COMPAT_GENERIC) += compat_audit.o
 
 obj-$(CONFIG_SWIOTLB) += swiotlb.o
 obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o
index 76bbed4..1d726a2 100644 (file)
@@ -30,11 +30,17 @@ static unsigned signal_class[] = {
 
 int audit_classify_arch(int arch)
 {
-       return 0;
+       if (audit_is_compat(arch))
+               return 1;
+       else
+               return 0;
 }
 
 int audit_classify_syscall(int abi, unsigned syscall)
 {
+       if (audit_is_compat(abi))
+               return audit_classify_compat_syscall(abi, syscall);
+
        switch(syscall) {
 #ifdef __NR_open
        case __NR_open:
@@ -57,6 +63,13 @@ int audit_classify_syscall(int abi, unsigned syscall)
 
 static int __init audit_classes_init(void)
 {
+#ifdef CONFIG_AUDIT_COMPAT_GENERIC
+       audit_register_class(AUDIT_CLASS_WRITE_32, compat_write_class);
+       audit_register_class(AUDIT_CLASS_READ_32, compat_read_class);
+       audit_register_class(AUDIT_CLASS_DIR_WRITE_32, compat_dir_class);
+       audit_register_class(AUDIT_CLASS_CHATTR_32, compat_chattr_class);
+       audit_register_class(AUDIT_CLASS_SIGNAL_32, compat_signal_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);
diff --git a/lib/compat_audit.c b/lib/compat_audit.c
new file mode 100644 (file)
index 0000000..873f75b
--- /dev/null
@@ -0,0 +1,50 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <asm/unistd32.h>
+
+unsigned compat_dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+unsigned compat_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+unsigned compat_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned compat_chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+unsigned compat_signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_compat_syscall(int abi, unsigned syscall)
+{
+       switch (syscall) {
+#ifdef __NR_open
+       case __NR_open:
+               return 2;
+#endif
+#ifdef __NR_openat
+       case __NR_openat:
+               return 3;
+#endif
+#ifdef __NR_socketcall
+       case __NR_socketcall:
+               return 4;
+#endif
+       case __NR_execve:
+               return 5;
+       default:
+               return 1;
+       }
+}
index d7813e6..f380af7 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -446,6 +446,54 @@ unsigned long vm_commit_limit(void)
        return allowed;
 }
 
+/**
+ * get_cmdline() - copy the cmdline value to a buffer.
+ * @task:     the task whose cmdline value to copy.
+ * @buffer:   the buffer to copy to.
+ * @buflen:   the length of the buffer. Larger cmdline values are truncated
+ *            to this length.
+ * Returns the size of the cmdline field copied. Note that the copy does
+ * not guarantee an ending NULL byte.
+ */
+int get_cmdline(struct task_struct *task, char *buffer, int buflen)
+{
+       int res = 0;
+       unsigned int len;
+       struct mm_struct *mm = get_task_mm(task);
+       if (!mm)
+               goto out;
+       if (!mm->arg_end)
+               goto out_mm;    /* Shh! No looking before we're done */
+
+       len = mm->arg_end - mm->arg_start;
+
+       if (len > buflen)
+               len = buflen;
+
+       res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+
+       /*
+        * If the nul at the end of args has been overwritten, then
+        * assume application is using setproctitle(3).
+        */
+       if (res > 0 && buffer[res-1] != '\0' && len < buflen) {
+               len = strnlen(buffer, res);
+               if (len < res) {
+                       res = len;
+               } else {
+                       len = mm->env_end - mm->env_start;
+                       if (len > buflen - res)
+                               len = buflen - res;
+                       res += access_process_vm(task, mm->env_start,
+                                                buffer+res, len, 0);
+                       res = strnlen(buffer, res);
+               }
+       }
+out_mm:
+       mmput(mm);
+out:
+       return res;
+}
 
 /* Tracepoints definitions. */
 EXPORT_TRACEPOINT_SYMBOL(kmalloc);
index aab9fa5..90987d1 100644 (file)
@@ -40,7 +40,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
 
        ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
        audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u",
-                        current->pid,
+                        task_pid_nr(current),
                         from_kuid(&init_user_ns, current_cred()->uid),
                         from_kuid(&init_user_ns, audit_get_loginuid(current)),
                         audit_get_sessionid(current));
index 9a62045..69fdf3b 100644 (file)
@@ -220,7 +220,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
         */
        BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
 
-       audit_log_format(ab, " pid=%d comm=", tsk->pid);
+       audit_log_format(ab, " pid=%d comm=", task_pid_nr(tsk));
        audit_log_untrustedstring(ab, tsk->comm);
 
        switch (a->type) {
@@ -278,9 +278,12 @@ static void dump_common_audit_data(struct audit_buffer *ab,
        }
        case LSM_AUDIT_DATA_TASK:
                tsk = a->u.tsk;
-               if (tsk && tsk->pid) {
-                       audit_log_format(ab, " pid=%d comm=", tsk->pid);
-                       audit_log_untrustedstring(ab, tsk->comm);
+               if (tsk) {
+                       pid_t pid = task_pid_nr(tsk);
+                       if (pid) {
+                               audit_log_format(ab, " pid=%d comm=", pid);
+                               audit_log_untrustedstring(ab, tsk->comm);
+                       }
                }
                break;
        case LSM_AUDIT_DATA_NET: