diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/compat_ptrace.h | 1 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 28 |
2 files changed, 29 insertions, 0 deletions
diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h index cde81fa64f89..a2be3a978d5c 100644 --- a/arch/s390/kernel/compat_ptrace.h +++ b/arch/s390/kernel/compat_ptrace.h | |||
@@ -42,6 +42,7 @@ struct user_regs_struct32 | |||
42 | u32 gprs[NUM_GPRS]; | 42 | u32 gprs[NUM_GPRS]; |
43 | u32 acrs[NUM_ACRS]; | 43 | u32 acrs[NUM_ACRS]; |
44 | u32 orig_gpr2; | 44 | u32 orig_gpr2; |
45 | /* nb: there's a 4-byte hole here */ | ||
45 | s390_fp_regs fp_regs; | 46 | s390_fp_regs fp_regs; |
46 | /* | 47 | /* |
47 | * These per registers are in here so that gdb can modify them | 48 | * These per registers are in here so that gdb can modify them |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 2815bfe348a6..c8b08289eb87 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -170,6 +170,13 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr) | |||
170 | */ | 170 | */ |
171 | tmp = (addr_t) task_pt_regs(child)->orig_gpr2; | 171 | tmp = (addr_t) task_pt_regs(child)->orig_gpr2; |
172 | 172 | ||
173 | } else if (addr < (addr_t) &dummy->regs.fp_regs) { | ||
174 | /* | ||
175 | * prevent reads of padding hole between | ||
176 | * orig_gpr2 and fp_regs on s390. | ||
177 | */ | ||
178 | tmp = 0; | ||
179 | |||
173 | } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { | 180 | } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { |
174 | /* | 181 | /* |
175 | * floating point regs. are stored in the thread structure | 182 | * floating point regs. are stored in the thread structure |
@@ -270,6 +277,13 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) | |||
270 | */ | 277 | */ |
271 | task_pt_regs(child)->orig_gpr2 = data; | 278 | task_pt_regs(child)->orig_gpr2 = data; |
272 | 279 | ||
280 | } else if (addr < (addr_t) &dummy->regs.fp_regs) { | ||
281 | /* | ||
282 | * prevent writes of padding hole between | ||
283 | * orig_gpr2 and fp_regs on s390. | ||
284 | */ | ||
285 | return 0; | ||
286 | |||
273 | } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { | 287 | } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { |
274 | /* | 288 | /* |
275 | * floating point regs. are stored in the thread structure | 289 | * floating point regs. are stored in the thread structure |
@@ -428,6 +442,13 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr) | |||
428 | */ | 442 | */ |
429 | tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4); | 443 | tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4); |
430 | 444 | ||
445 | } else if (addr < (addr_t) &dummy32->regs.fp_regs) { | ||
446 | /* | ||
447 | * prevent reads of padding hole between | ||
448 | * orig_gpr2 and fp_regs on s390. | ||
449 | */ | ||
450 | tmp = 0; | ||
451 | |||
431 | } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { | 452 | } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { |
432 | /* | 453 | /* |
433 | * floating point regs. are stored in the thread structure | 454 | * floating point regs. are stored in the thread structure |
@@ -514,6 +535,13 @@ static int __poke_user_compat(struct task_struct *child, | |||
514 | */ | 535 | */ |
515 | *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp; | 536 | *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp; |
516 | 537 | ||
538 | } else if (addr < (addr_t) &dummy32->regs.fp_regs) { | ||
539 | /* | ||
540 | * prevent writess of padding hole between | ||
541 | * orig_gpr2 and fp_regs on s390. | ||
542 | */ | ||
543 | return 0; | ||
544 | |||
517 | } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { | 545 | } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { |
518 | /* | 546 | /* |
519 | * floating point regs. are stored in the thread structure | 547 | * floating point regs. are stored in the thread structure |