Merge tag 'audit-pr-20190507' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoor...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 May 2019 02:06:04 +0000 (19:06 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 May 2019 02:06:04 +0000 (19:06 -0700)
Pull audit updates from Paul Moore:
 "We've got a reasonably broad set of audit patches for the v5.2 merge
  window, the highlights are below:

   - The biggest change, and the source of all the arch/* changes, is
     the patchset from Dmitry to help enable some of the work he is
     doing around PTRACE_GET_SYSCALL_INFO.

     To be honest, including this in the audit tree is a bit of a
     stretch, but it does help move audit a little further along towards
     proper syscall auditing for all arches, and everyone else seemed to
     agree that audit was a "good" spot for this to land (or maybe they
     just didn't want to merge it? dunno.).

   - We can now audit time/NTP adjustments.

   - We continue the work to connect associated audit records into a
     single event"

* tag 'audit-pr-20190507' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: (21 commits)
  audit: fix a memory leak bug
  ntp: Audit NTP parameters adjustment
  timekeeping: Audit clock adjustments
  audit: purge unnecessary list_empty calls
  audit: link integrity evm_write_xattrs record to syscall event
  syscall_get_arch: add "struct task_struct *" argument
  unicore32: define syscall_get_arch()
  Move EM_UNICORE to uapi/linux/elf-em.h
  nios2: define syscall_get_arch()
  nds32: define syscall_get_arch()
  Move EM_NDS32 to uapi/linux/elf-em.h
  m68k: define syscall_get_arch()
  hexagon: define syscall_get_arch()
  Move EM_HEXAGON to uapi/linux/elf-em.h
  h8300: define syscall_get_arch()
  c6x: define syscall_get_arch()
  arc: define syscall_get_arch()
  Move EM_ARCOMPACT and EM_ARCV2 to uapi/linux/elf-em.h
  audit: Make audit_log_cap and audit_copy_inode static
  audit: connect LOGIN record to its syscall record
  ...

26 files changed:
1  2 
arch/arc/include/asm/syscall.h
arch/arm/include/asm/syscall.h
arch/arm64/include/asm/syscall.h
arch/c6x/include/asm/syscall.h
arch/csky/include/asm/syscall.h
arch/h8300/include/asm/syscall.h
arch/hexagon/include/asm/syscall.h
arch/ia64/include/asm/syscall.h
arch/microblaze/include/asm/syscall.h
arch/mips/include/asm/syscall.h
arch/mips/kernel/ptrace.c
arch/nds32/include/asm/syscall.h
arch/nios2/include/asm/syscall.h
arch/openrisc/include/asm/syscall.h
arch/parisc/include/asm/syscall.h
arch/powerpc/include/asm/syscall.h
arch/riscv/include/asm/syscall.h
arch/s390/include/asm/syscall.h
arch/sh/include/asm/syscall_32.h
arch/sh/include/asm/syscall_64.h
arch/sparc/include/asm/syscall.h
arch/x86/include/asm/syscall.h
arch/xtensa/include/asm/syscall.h
include/asm-generic/syscall.h
kernel/seccomp.c
kernel/time/timekeeping.c

Simple merge
@@@ -65,15 -82,29 +65,15 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         const unsigned long *args)
  {
 -      if (n == 0)
 -              return;
 -
 -      if (i + n > SYSCALL_MAX_ARGS) {
 -              pr_warn("%s called with max args %d, handling only %d\n",
 -                      __func__, i + n, SYSCALL_MAX_ARGS);
 -              n = SYSCALL_MAX_ARGS - i;
 -      }
 -
 -      if (i == 0) {
 -              regs->ARM_ORIG_r0 = args[0];
 -              args++;
 -              i++;
 -              n--;
 -      }
 -
 -      memcpy(&regs->ARM_r0 + i, args, n * sizeof(args[0]));
 +      regs->ARM_ORIG_r0 = args[0];
 +      args++;
 +
 +      memcpy(&regs->ARM_r0 + 1, args, 5 * sizeof(args[0]));
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
        /* ARM tasks don't change audit architectures on the fly. */
        return AUDIT_ARCH_ARM;
Simple merge
@@@ -59,14 -85,46 +60,20 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         const unsigned long *args)
  {
 -      switch (i) {
 -      case 0:
 -              if (!n--)
 -                      break;
 -              regs->a4 = *args++;
 -      case 1:
 -              if (!n--)
 -                      break;
 -              regs->b4 = *args++;
 -      case 2:
 -              if (!n--)
 -                      break;
 -              regs->a6 = *args++;
 -      case 3:
 -              if (!n--)
 -                      break;
 -              regs->b6 = *args++;
 -      case 4:
 -              if (!n--)
 -                      break;
 -              regs->a8 = *args++;
 -      case 5:
 -              if (!n--)
 -                      break;
 -              regs->a9 = *args++;
 -      case 6:
 -              if (!n)
 -                      break;
 -      default:
 -              BUG();
 -      }
 +      regs->a4 = *args++;
 +      regs->b4 = *args++;
 +      regs->a6 = *args++;
 +      regs->b6 = *args++;
 +      regs->a8 = *args++;
 +      regs->a9 = *args;
  }
  
+ static inline int syscall_get_arch(struct task_struct *task)
+ {
+       return IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)
+               ? AUDIT_ARCH_C6XBE : AUDIT_ARCH_C6X;
+ }
  #endif /* __ASM_C6X_SYSCALLS_H */
Simple merge
@@@ -17,16 -18,41 +18,21 @@@ syscall_get_nr(struct task_struct *task
  
  static inline void
  syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
 -                    unsigned int i, unsigned int n, unsigned long *args)
 +                    unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 -
 -      while (n > 0) {
 -              switch (i) {
 -              case 0:
 -                      *args++ = regs->er1;
 -                      break;
 -              case 1:
 -                      *args++ = regs->er2;
 -                      break;
 -              case 2:
 -                      *args++ = regs->er3;
 -                      break;
 -              case 3:
 -                      *args++ = regs->er4;
 -                      break;
 -              case 4:
 -                      *args++ = regs->er5;
 -                      break;
 -              case 5:
 -                      *args++ = regs->er6;
 -                      break;
 -              }
 -              i++;
 -              n--;
 -      }
 +      *args++ = regs->er1;
 +      *args++ = regs->er2;
 +      *args++ = regs->er3;
 +      *args++ = regs->er4;
 +      *args++ = regs->er5;
 +      *args   = regs->er6;
  }
  
+ static inline int
+ syscall_get_arch(struct task_struct *task)
+ {
+       return AUDIT_ARCH_H8300;
+ }
  
  
  /* Misc syscall related bits */
@@@ -37,8 -39,16 +39,14 @@@ static inline long syscall_get_nr(struc
  
  static inline void syscall_get_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 -      memcpy(args, &(&regs->r00)[i], n * sizeof(args[0]));
 +      memcpy(args, &(&regs->r00)[0], 6 * sizeof(args[0]));
  }
+ static inline int syscall_get_arch(struct task_struct *task)
+ {
+       return AUDIT_ARCH_HEXAGON;
+ }
  #endif
@@@ -69,12 -73,15 +69,12 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 -
 -      ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
 +      ia64_syscall_get_set_arguments(task, regs, args, 1);
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
        return AUDIT_ARCH_IA64;
  }
Simple merge
Simple merge
@@@ -1418,8 -1418,8 +1418,8 @@@ asmlinkage long syscall_trace_enter(str
                unsigned long args[6];
  
                sd.nr = syscall;
-               sd.arch = syscall_get_arch();
+               sd.arch = syscall_get_arch(current);
 -              syscall_get_arguments(current, regs, 0, 6, args);
 +              syscall_get_arguments(current, regs, args);
                for (i = 0; i < 6; i++)
                        sd.args[i] = args[i];
                sd.instruction_pointer = KSTK_EIP(current);
@@@ -136,13 -161,37 +137,21 @@@ void syscall_get_arguments(struct task_
   *
   * It's only valid to call this when @task is stopped for tracing on
   * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
 - * It's invalid to call this with @i + @n > 6; we only support system calls
 - * taking up to 6 arguments.
   */
  void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
 -                         unsigned int i, unsigned int n,
                           const unsigned long *args)
  {
 -      if (n == 0)
 -              return;
 -
 -      if (i + n > SYSCALL_MAX_ARGS) {
 -              pr_warn("%s called with max args %d, handling only %d\n",
 -                      __func__, i + n, SYSCALL_MAX_ARGS);
 -              n = SYSCALL_MAX_ARGS - i;
 -      }
 -
 -      if (i == 0) {
 -              regs->orig_r0 = args[0];
 -              args++;
 -              i++;
 -              n--;
 -      }
 +      regs->orig_r0 = args[0];
 +      args++;
  
 -      memcpy(&regs->uregs[0] + i, args, n * sizeof(args[0]));
 +      memcpy(&regs->uregs[0] + 1, args, 5 * sizeof(args[0]));
  }
+ static inline int
+ syscall_get_arch(struct task_struct *task)
+ {
+       return IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)
+               ? AUDIT_ARCH_NDS32BE : AUDIT_ARCH_NDS32;
+ }
  #endif /* _ASM_NDS32_SYSCALL_H */
@@@ -69,14 -98,47 +70,19 @@@ static inline void syscall_get_argument
  }
  
  static inline void syscall_set_arguments(struct task_struct *task,
 -      struct pt_regs *regs, unsigned int i, unsigned int n,
 -      const unsigned long *args)
 +      struct pt_regs *regs, const unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 -
 -      switch (i) {
 -      case 0:
 -              if (!n--)
 -                      break;
 -              regs->r4 = *args++;
 -      case 1:
 -              if (!n--)
 -                      break;
 -              regs->r5 = *args++;
 -      case 2:
 -              if (!n--)
 -                      break;
 -              regs->r6 = *args++;
 -      case 3:
 -              if (!n--)
 -                      break;
 -              regs->r7 = *args++;
 -      case 4:
 -              if (!n--)
 -                      break;
 -              regs->r8 = *args++;
 -      case 5:
 -              if (!n--)
 -                      break;
 -              regs->r9 = *args++;
 -      case 6:
 -              if (!n)
 -                      break;
 -      default:
 -              BUG();
 -      }
 +      regs->r4 = *args++;
 +      regs->r5 = *args++;
 +      regs->r6 = *args++;
 +      regs->r7 = *args++;
 +      regs->r8 = *args++;
 +      regs->r9 = *args;
  }
  
+ static inline int syscall_get_arch(struct task_struct *task)
+ {
+       return AUDIT_ARCH_NIOS2;
+ }
  #endif
@@@ -63,12 -65,14 +63,12 @@@ syscall_get_arguments(struct task_struc
  
  static inline void
  syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
 -                    unsigned int i, unsigned int n, const unsigned long *args)
 +                    const unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 -
 -      memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
 +      memcpy(&regs->gpr[3], args, 6 * sizeof(args[0]));
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
        return AUDIT_ARCH_OPENRISC;
  }
Simple merge
@@@ -86,17 -88,26 +86,23 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         const unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 -      memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
 +      memcpy(&regs->gpr[3], args, 6 * sizeof(args[0]));
  
        /* Also copy the first argument into orig_gpr3 */
 -      if (i == 0 && n > 0)
 -              regs->orig_gpr3 = args[0];
 +      regs->orig_gpr3 = args[0];
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
-       int arch = is_32bit_task() ? AUDIT_ARCH_PPC : AUDIT_ARCH_PPC64;
+       int arch;
+       if (IS_ENABLED(CONFIG_PPC64) && !test_tsk_thread_flag(task, TIF_32BIT))
+               arch = AUDIT_ARCH_PPC64;
+       else
+               arch = AUDIT_ARCH_PPC;
  #ifdef __LITTLE_ENDIAN__
        arch |= __AUDIT_ARCH_LE;
  #endif
@@@ -81,14 -87,20 +81,14 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         const unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 -        if (i == 0) {
 -                regs->orig_a0 = args[0];
 -                args++;
 -                i++;
 -                n--;
 -        }
 -      memcpy(&regs->a1 + i * sizeof(regs->a1), args, n * sizeof(regs->a0));
 +      regs->orig_a0 = args[0];
 +      args++;
 +      memcpy(&regs->a1, args, 5 * sizeof(regs->a1));
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
  #ifdef CONFIG_64BIT
        return AUDIT_ARCH_RISCV64;
@@@ -69,20 -81,21 +69,20 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         const unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 +      unsigned int n = 6;
 +
        while (n-- > 0)
 -              if (i + n > 0)
 -                      regs->gprs[2 + i + n] = args[n];
 -      if (i == 0)
 -              regs->orig_gpr2 = args[0];
 +              if (n > 0)
 +                      regs->gprs[2 + n] = args[n];
 +      regs->orig_gpr2 = args[0];
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
  #ifdef CONFIG_COMPAT
-       if (test_tsk_thread_flag(current, TIF_31BIT))
+       if (test_tsk_thread_flag(task, TIF_31BIT))
                return AUDIT_ARCH_S390;
  #endif
        return AUDIT_ARCH_S390X;
@@@ -62,17 -76,26 +62,17 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         const unsigned long *args)
  {
 -      /* Same note as above applies */
 -      BUG_ON(i);
 -
 -      switch (n) {
 -      case 6: regs->regs[1] = args[5];
 -      case 5: regs->regs[0] = args[4];
 -      case 4: regs->regs[7] = args[3];
 -      case 3: regs->regs[6] = args[2];
 -      case 2: regs->regs[5] = args[1];
 -      case 1: regs->regs[4] = args[0];
 -              break;
 -      default:
 -              BUG();
 -      }
 +      regs->regs[1] = args[5];
 +      regs->regs[0] = args[4];
 +      regs->regs[7] = args[3];
 +      regs->regs[6] = args[2];
 +      regs->regs[5] = args[1];
 +      regs->regs[4] = args[0];
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
        int arch = AUDIT_ARCH_SH;
  
@@@ -54,12 -56,14 +54,12 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         const unsigned long *args)
  {
 -      BUG_ON(i + n > 6);
 -      memcpy(&regs->regs[2 + i], args, n * sizeof(args[0]));
 +      memcpy(&regs->regs[2], args, 6 * sizeof(args[0]));
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
        int arch = AUDIT_ARCH_SH;
  
@@@ -119,18 -119,20 +119,19 @@@ static inline void syscall_get_argument
  
  static inline void syscall_set_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
 -                                       unsigned int i, unsigned int n,
                                         const unsigned long *args)
  {
 -      unsigned int j;
 +      unsigned int i;
  
 -      for (j = 0; j < n; j++)
 -              regs->u_regs[UREG_I0 + i + j] = args[j];
 +      for (i = 0; i < 6; i++)
 +              regs->u_regs[UREG_I0 + i] = args[i];
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
  #if defined(CONFIG_SPARC64) && defined(CONFIG_COMPAT)
-       return in_compat_syscall() ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64;
+       return test_tsk_thread_flag(task, TIF_32BIT)
+               ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64;
  #elif defined(CONFIG_SPARC64)
        return AUDIT_ARCH_SPARC64;
  #else
@@@ -141,29 -180,68 +141,31 @@@ static inline void syscall_set_argument
                                         const unsigned long *args)
  {
  # ifdef CONFIG_IA32_EMULATION
 -      if (task->thread_info.status & TS_COMPAT)
 -              switch (i) {
 -              case 0:
 -                      if (!n--) break;
 -                      regs->bx = *args++;
 -              case 1:
 -                      if (!n--) break;
 -                      regs->cx = *args++;
 -              case 2:
 -                      if (!n--) break;
 -                      regs->dx = *args++;
 -              case 3:
 -                      if (!n--) break;
 -                      regs->si = *args++;
 -              case 4:
 -                      if (!n--) break;
 -                      regs->di = *args++;
 -              case 5:
 -                      if (!n--) break;
 -                      regs->bp = *args++;
 -              case 6:
 -                      if (!n--) break;
 -              default:
 -                      BUG();
 -                      break;
 -              }
 -      else
 +      if (task->thread_info.status & TS_COMPAT) {
 +              regs->bx = *args++;
 +              regs->cx = *args++;
 +              regs->dx = *args++;
 +              regs->si = *args++;
 +              regs->di = *args++;
 +              regs->bp = *args;
 +      } else
  # endif
 -              switch (i) {
 -              case 0:
 -                      if (!n--) break;
 -                      regs->di = *args++;
 -              case 1:
 -                      if (!n--) break;
 -                      regs->si = *args++;
 -              case 2:
 -                      if (!n--) break;
 -                      regs->dx = *args++;
 -              case 3:
 -                      if (!n--) break;
 -                      regs->r10 = *args++;
 -              case 4:
 -                      if (!n--) break;
 -                      regs->r8 = *args++;
 -              case 5:
 -                      if (!n--) break;
 -                      regs->r9 = *args++;
 -              case 6:
 -                      if (!n--) break;
 -              default:
 -                      BUG();
 -                      break;
 -              }
 +      {
 +              regs->di = *args++;
 +              regs->si = *args++;
 +              regs->dx = *args++;
 +              regs->r10 = *args++;
 +              regs->r8 = *args++;
 +              regs->r9 = *args;
 +      }
  }
  
- static inline int syscall_get_arch(void)
+ static inline int syscall_get_arch(struct task_struct *task)
  {
        /* x32 tasks should be considered AUDIT_ARCH_X86_64. */
-       return in_ia32_syscall() ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
+       return (IS_ENABLED(CONFIG_IA32_EMULATION) &&
+               task->thread_info.status & TS_COMPAT)
+               ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
  }
  #endif        /* CONFIG_X86_32 */
  
Simple merge
Simple merge
@@@ -148,8 -148,8 +148,8 @@@ static void populate_seccomp_data(struc
        unsigned long args[6];
  
        sd->nr = syscall_get_nr(task, regs);
-       sd->arch = syscall_get_arch();
+       sd->arch = syscall_get_arch(task);
 -      syscall_get_arguments(task, regs, 0, 6, args);
 +      syscall_get_arguments(task, regs, args);
        sd->args[0] = args[0];
        sd->args[1] = args[1];
        sd->args[2] = args[2];
Simple merge