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: David Woodhouse <dwmw2@infradead.org>
This commit is contained in:
@@ -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));
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user