linux-next: manual merge of the tip tree with the audit tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,

Today's linux-next merge of the tip tree got a conflict in
arch/x86/kernel/ptrace.c between commit 91397401bb50 ("ARCH: AUDIT:
audit_syscall_entry() should not require the arch") from the audit tree
and commit e0ffbaabc46d ("x86: Split syscall_trace_enter into two
phases") from the tip tree.

I fixed it up (see below - there is more cleanup possible since
do_audit_syscall_entry() no longer needs its "arch" argument) and can
carry the fix as necessary (no action is required).

-- 
Cheers,
Stephen Rothwell                    sfr@xxxxxxxxxxxxxxxx

diff --cc arch/x86/kernel/ptrace.c
index eb1c87f0b03b,29576c244699..000000000000
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@@ -1441,24 -1441,126 +1441,126 @@@ void send_sigtrap(struct task_struct *t
  	force_sig_info(SIGTRAP, &info, tsk);
  }
  
- 
- #ifdef CONFIG_X86_32
- # define IS_IA32	1
- #elif defined CONFIG_IA32_EMULATION
- # define IS_IA32	is_compat_task()
- #else
- # define IS_IA32	0
+ 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);
+ 	}
+ }
  
  /*
-  * We must return the syscall number to actually look up in the table.
-  * This can be -1L to skip running any syscall at all.
+  * We can return 0 to resume the syscall or anything else to go to phase
+  * 2.  If we resume the syscall, we need to put something appropriate in
+  * regs->orig_ax.
+  *
+  * NB: We don't have full pt_regs here, but regs->orig_ax and regs->ax
+  * are fully functional.
+  *
+  * For phase 2's benefit, our return value is:
+  * 0:			resume the syscall
+  * 1:			go to phase 2; no seccomp phase 2 needed
+  * anything else:	go to phase 2; pass return value to seccomp
   */
- long syscall_trace_enter(struct pt_regs *regs)
+ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
+ {
+ 	unsigned long ret = 0;
+ 	u32 work;
+ 
+ 	BUG_ON(regs != task_pt_regs(current));
+ 
+ 	work = ACCESS_ONCE(current_thread_info()->flags) &
+ 		_TIF_WORK_SYSCALL_ENTRY;
+ 
+ 	/*
+ 	 * If TIF_NOHZ is set, we are required to call user_exit() before
+ 	 * doing anything that could touch RCU.
+ 	 */
+ 	if (work & _TIF_NOHZ) {
+ 		user_exit();
+ 		work &= ~TIF_NOHZ;
+ 	}
+ 
+ #ifdef CONFIG_SECCOMP
+ 	/*
+ 	 * Do seccomp first -- it should minimize exposure of other
+ 	 * code, and keeping seccomp fast is probably more valuable
+ 	 * than the rest of this.
+ 	 */
+ 	if (work & _TIF_SECCOMP) {
+ 		struct seccomp_data sd;
+ 
+ 		sd.arch = arch;
+ 		sd.nr = regs->orig_ax;
+ 		sd.instruction_pointer = regs->ip;
+ #ifdef CONFIG_X86_64
+ 		if (arch == AUDIT_ARCH_X86_64) {
+ 			sd.args[0] = regs->di;
+ 			sd.args[1] = regs->si;
+ 			sd.args[2] = regs->dx;
+ 			sd.args[3] = regs->r10;
+ 			sd.args[4] = regs->r8;
+ 			sd.args[5] = regs->r9;
+ 		} else
+ #endif
+ 		{
+ 			sd.args[0] = regs->bx;
+ 			sd.args[1] = regs->cx;
+ 			sd.args[2] = regs->dx;
+ 			sd.args[3] = regs->si;
+ 			sd.args[4] = regs->di;
+ 			sd.args[5] = regs->bp;
+ 		}
+ 
+ 		BUILD_BUG_ON(SECCOMP_PHASE1_OK != 0);
+ 		BUILD_BUG_ON(SECCOMP_PHASE1_SKIP != 1);
+ 
+ 		ret = seccomp_phase1(&sd);
+ 		if (ret == SECCOMP_PHASE1_SKIP) {
+ 			regs->orig_ax = -1;
+ 			ret = 0;
+ 		} else if (ret != SECCOMP_PHASE1_OK) {
+ 			return ret;  /* Go directly to phase 2 */
+ 		}
+ 
+ 		work &= ~_TIF_SECCOMP;
+ 	}
+ #endif
+ 
+ 	/* Do our best to finish without phase 2. */
+ 	if (work == 0)
+ 		return ret;  /* seccomp and/or nohz only (ret == 0 here) */
+ 
+ #ifdef CONFIG_AUDITSYSCALL
+ 	if (work == _TIF_SYSCALL_AUDIT) {
+ 		/*
+ 		 * If there is no more work to be done except auditing,
+ 		 * then audit in phase 1.  Phase 2 always audits, so, if
+ 		 * we audit here, then we can't go on to phase 2.
+ 		 */
+ 		do_audit_syscall_entry(regs, arch);
+ 		return 0;
+ 	}
+ #endif
+ 
+ 	return 1;  /* Something is enabled that we can't handle in phase 1 */
+ }
+ 
+ /* Returns the syscall nr to run (which should match regs->orig_ax). */
+ long syscall_trace_enter_phase2(struct pt_regs *regs, u32 arch,
+ 				unsigned long phase1_result)
  {
  	long ret = 0;
+ 	u32 work = ACCESS_ONCE(current_thread_info()->flags) &
+ 		_TIF_WORK_SYSCALL_ENTRY;
  
- 	user_exit();
+ 	BUG_ON(regs != task_pt_regs(current));
  
  	/*
  	 * If we stepped into a sysenter/syscall insn, it trapped in

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Kernel]     [Linux USB Development]     [Yosemite News]     [Linux SCSI]

  Powered by Linux