diff options
Diffstat (limited to 'arch/tile/kernel/ptrace.c')
-rw-r--r-- | arch/tile/kernel/ptrace.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 5b20c2874d51..e92e40527d6d 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c | |||
@@ -45,19 +45,20 @@ void ptrace_disable(struct task_struct *child) | |||
45 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 45 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
46 | } | 46 | } |
47 | 47 | ||
48 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 48 | long arch_ptrace(struct task_struct *child, long request, |
49 | unsigned long addr, unsigned long data) | ||
49 | { | 50 | { |
50 | unsigned long __user *datap = (long __user __force *)data; | 51 | unsigned long __user *datap = (long __user __force *)data; |
51 | unsigned long tmp; | 52 | unsigned long tmp; |
52 | int i; | ||
53 | long ret = -EIO; | 53 | long ret = -EIO; |
54 | unsigned long *childregs; | ||
55 | char *childreg; | 54 | char *childreg; |
55 | struct pt_regs copyregs; | ||
56 | int ex1_offset; | ||
56 | 57 | ||
57 | switch (request) { | 58 | switch (request) { |
58 | 59 | ||
59 | case PTRACE_PEEKUSR: /* Read register from pt_regs. */ | 60 | case PTRACE_PEEKUSR: /* Read register from pt_regs. */ |
60 | if (addr < 0 || addr >= PTREGS_SIZE) | 61 | if (addr >= PTREGS_SIZE) |
61 | break; | 62 | break; |
62 | childreg = (char *)task_pt_regs(child) + addr; | 63 | childreg = (char *)task_pt_regs(child) + addr; |
63 | #ifdef CONFIG_COMPAT | 64 | #ifdef CONFIG_COMPAT |
@@ -76,9 +77,19 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
76 | break; | 77 | break; |
77 | 78 | ||
78 | case PTRACE_POKEUSR: /* Write register in pt_regs. */ | 79 | case PTRACE_POKEUSR: /* Write register in pt_regs. */ |
79 | if (addr < 0 || addr >= PTREGS_SIZE) | 80 | if (addr >= PTREGS_SIZE) |
80 | break; | 81 | break; |
81 | childreg = (char *)task_pt_regs(child) + addr; | 82 | childreg = (char *)task_pt_regs(child) + addr; |
83 | |||
84 | /* Guard against overwrites of the privilege level. */ | ||
85 | ex1_offset = PTREGS_OFFSET_EX1; | ||
86 | #if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN) | ||
87 | if (is_compat_task()) /* point at low word */ | ||
88 | ex1_offset += sizeof(compat_long_t); | ||
89 | #endif | ||
90 | if (addr == ex1_offset) | ||
91 | data = PL_ICS_EX1(USER_PL, EX1_ICS(data)); | ||
92 | |||
82 | #ifdef CONFIG_COMPAT | 93 | #ifdef CONFIG_COMPAT |
83 | if (is_compat_task()) { | 94 | if (is_compat_task()) { |
84 | if (addr & (sizeof(compat_long_t)-1)) | 95 | if (addr & (sizeof(compat_long_t)-1)) |
@@ -95,24 +106,19 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
95 | break; | 106 | break; |
96 | 107 | ||
97 | case PTRACE_GETREGS: /* Get all registers from the child. */ | 108 | case PTRACE_GETREGS: /* Get all registers from the child. */ |
98 | if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) | 109 | if (copy_to_user(datap, task_pt_regs(child), |
99 | break; | 110 | sizeof(struct pt_regs)) == 0) { |
100 | childregs = (long *)task_pt_regs(child); | 111 | ret = 0; |
101 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) { | ||
102 | ret = __put_user(childregs[i], &datap[i]); | ||
103 | if (ret != 0) | ||
104 | break; | ||
105 | } | 112 | } |
106 | break; | 113 | break; |
107 | 114 | ||
108 | case PTRACE_SETREGS: /* Set all registers in the child. */ | 115 | case PTRACE_SETREGS: /* Set all registers in the child. */ |
109 | if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) | 116 | if (copy_from_user(©regs, datap, |
110 | break; | 117 | sizeof(struct pt_regs)) == 0) { |
111 | childregs = (long *)task_pt_regs(child); | 118 | copyregs.ex1 = |
112 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) { | 119 | PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1)); |
113 | ret = __get_user(childregs[i], &datap[i]); | 120 | *task_pt_regs(child) = copyregs; |
114 | if (ret != 0) | 121 | ret = 0; |
115 | break; | ||
116 | } | 122 | } |
117 | break; | 123 | break; |
118 | 124 | ||