Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17888225 authored by David Woodhouse's avatar David Woodhouse
Browse files

Fix missing audit_syscall_exit() on ppc64 sigsuspend exit path



When we leave sigsuspend() directly into a signal handler, we don't want
to go via the normal syscall exit path -- it'll corrupt r4 and r5 which
are supposed to be giving information to the signal handler, and it'll
give us one more single-step SIGTRAP than we need if single-stepping is
in operation.

However, we _should_ be calling audit_syscall_exit(), which would
normally get invoked in that patch. It's not wonderfully pretty, but I
suspect the best answer is just to call it directly...

Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 3c789a19
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -68,6 +68,7 @@ int main(void)
	DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
	DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
#endif /* CONFIG_ALTIVEC */
#endif /* CONFIG_ALTIVEC */
	DEFINE(MM, offsetof(struct task_struct, mm));
	DEFINE(MM, offsetof(struct task_struct, mm));
	DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));


	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
+12 −4
Original line number Original line Diff line number Diff line
@@ -276,12 +276,20 @@ _GLOBAL(ppc64_rt_sigsuspend)
_GLOBAL(ppc32_rt_sigsuspend)
_GLOBAL(ppc32_rt_sigsuspend)
	bl	.save_nvgprs
	bl	.save_nvgprs
	bl	.sys32_rt_sigsuspend
	bl	.sys32_rt_sigsuspend
	/* If sigsuspend() returns zero, we are going into a signal handler */
70:	cmpdi	0,r3,0
70:	cmpdi	0,r3,0
	beq	.ret_from_except
	/* If it returned an error, we need to return via syscall_exit to set
	/* If it returned -EINTR, we need to return via syscall_exit to set
	   the SO bit in cr0 and potentially stop for ptrace. */
	   the SO bit in cr0 and potentially stop for ptrace. */
	b	syscall_exit
	bne	syscall_exit
	/* If sigsuspend() returns zero, we are going into a signal handler. We
	   may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
	ld	r3,PACACURRENT(r13)
	ld	r4,AUDITCONTEXT(r3)
	cmpdi	0,r4,0
	beq	.ret_from_except	/* No audit_context: Leave immediately. */
	li	r4, 2			/* AUDITSC_FAILURE */
	li	r5,-4			/* It's always -EINTR */
	bl	.audit_syscall_exit
	b	.ret_from_except


_GLOBAL(ppc_fork)
_GLOBAL(ppc_fork)
	bl	.save_nvgprs
	bl	.save_nvgprs