aboutsummaryrefslogtreecommitdiff
path: root/arch/parisc/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel/ptrace.c')
-rw-r--r--arch/parisc/kernel/ptrace.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index c4f49e45129..e842ee233db 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -19,15 +19,15 @@
#include <linux/security.h>
#include <linux/compat.h>
#include <linux/signal.h>
+#include <linux/audit.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
#include <asm/processor.h>
#include <asm/asm-offsets.h>
/* PSW bits we allow the debugger to modify */
-#define USER_PSW_BITS (PSW_N | PSW_V | PSW_CB)
+#define USER_PSW_BITS (PSW_N | PSW_B | PSW_V | PSW_CB)
/*
* Called by kernel/ptrace.c when detaching..
@@ -110,7 +110,8 @@ void user_enable_block_step(struct task_struct *task)
pa_psw(task)->l = 0;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
long ret = -EIO;
@@ -120,11 +121,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Read the word at location addr in the USER area. For ptraced
processes, the kernel saves all regs on a syscall. */
case PTRACE_PEEKUSR:
- if ((addr & (sizeof(long)-1)) ||
- (unsigned long) addr >= sizeof(struct pt_regs))
+ if ((addr & (sizeof(unsigned long)-1)) ||
+ addr >= sizeof(struct pt_regs))
break;
tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, (unsigned long __user *) data);
break;
/* Write the word at location addr in the USER area. This will need
@@ -151,8 +152,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- if ((addr & (sizeof(long)-1)) ||
- (unsigned long) addr >= sizeof(struct pt_regs))
+ if ((addr & (sizeof(unsigned long)-1)) ||
+ addr >= sizeof(struct pt_regs))
break;
if ((addr >= PT_GR1 && addr <= PT_GR31) ||
addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
@@ -267,11 +268,28 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
long do_syscall_trace_enter(struct pt_regs *regs)
{
+ long ret = 0;
+
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs))
- return -1L;
-
- return regs->gr[20];
+ ret = -1L;
+
+#ifdef CONFIG_64BIT
+ if (!is_compat_task())
+ audit_syscall_entry(AUDIT_ARCH_PARISC64,
+ regs->gr[20],
+ regs->gr[26], regs->gr[25],
+ regs->gr[24], regs->gr[23]);
+ else
+#endif
+ audit_syscall_entry(AUDIT_ARCH_PARISC,
+ regs->gr[20] & 0xffffffff,
+ regs->gr[26] & 0xffffffff,
+ regs->gr[25] & 0xffffffff,
+ regs->gr[24] & 0xffffffff,
+ regs->gr[23] & 0xffffffff);
+
+ return ret ? : regs->gr[20];
}
void do_syscall_trace_exit(struct pt_regs *regs)
@@ -279,6 +297,8 @@ void do_syscall_trace_exit(struct pt_regs *regs)
int stepping = test_thread_flag(TIF_SINGLESTEP) ||
test_thread_flag(TIF_BLOCKSTEP);
+ audit_syscall_exit(regs);
+
if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, stepping);
}