aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-08-27 10:23:46 +0100
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-08-27 10:23:46 +0100
commit17888225c2f392bfdbac6c7f0713cbd9a4d02b05 (patch)
treecf11f005d3a973be9fd06eec243ded4b776c1502
parent3c789a19054034847afe80af2f23ebb0eebfbad6 (diff)
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>
-rw-r--r--arch/ppc64/kernel/asm-offsets.c1
-rw-r--r--arch/ppc64/kernel/entry.S16
2 files changed, 13 insertions, 4 deletions
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
index abb9e5b5da0..6f910fa2746 100644
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -68,6 +68,7 @@ int main(void)
DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
#endif /* CONFIG_ALTIVEC */
DEFINE(MM, offsetof(struct task_struct, mm));
+ DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
index b61572eb2a7..ae5d563ad93 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/ppc64/kernel/entry.S
@@ -276,12 +276,20 @@ _GLOBAL(ppc64_rt_sigsuspend)
_GLOBAL(ppc32_rt_sigsuspend)
bl .save_nvgprs
bl .sys32_rt_sigsuspend
- /* If sigsuspend() returns zero, we are going into a signal handler */
70: cmpdi 0,r3,0
- beq .ret_from_except
- /* If it returned -EINTR, we need to return via syscall_exit to set
+ /* If it returned an error, we need to return via syscall_exit to set
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)
bl .save_nvgprs