Commit bd028ecb authored by Paul Mackerras's avatar Paul Mackerras

PPC32: Fixes for bugs in exception handling in copy_to_user and clear_user.

parent 9a30d64b
...@@ -461,7 +461,7 @@ _GLOBAL(__copy_tofrom_user) ...@@ -461,7 +461,7 @@ _GLOBAL(__copy_tofrom_user)
53: 53:
#if !defined(CONFIG_8xx) #if !defined(CONFIG_8xx)
dcbt r3,r4 dcbt r3,r4
dcbz r11,r6 54: dcbz r11,r6
#endif #endif
/* had to move these to keep extable in order */ /* had to move these to keep extable in order */
.section __ex_table,"a" .section __ex_table,"a"
...@@ -470,7 +470,9 @@ _GLOBAL(__copy_tofrom_user) ...@@ -470,7 +470,9 @@ _GLOBAL(__copy_tofrom_user)
.long 71b,101f .long 71b,101f
.long 72b,102f .long 72b,102f
.long 73b,103f .long 73b,103f
.long 53b,105f #if !defined(CONFIG_8xx)
.long 54b,105f
#endif
.text .text
/* the main body of the cacheline loop */ /* the main body of the cacheline loop */
COPY_16_BYTES_WITHEX(0) COPY_16_BYTES_WITHEX(0)
...@@ -613,11 +615,11 @@ _GLOBAL(__clear_user) ...@@ -613,11 +615,11 @@ _GLOBAL(__clear_user)
add r4,r0,r4 add r4,r0,r4
subf r6,r0,r6 subf r6,r0,r6
srwi r0,r4,2 srwi r0,r4,2
andi. r4,r4,3
mtctr r0 mtctr r0
bdz 6f bdz 7f
1: stwu r5,4(r6) 1: stwu r5,4(r6)
bdnz 1b bdnz 1b
6: andi. r4,r4,3
/* clear byte sized chunks */ /* clear byte sized chunks */
7: cmpwi 0,r4,0 7: cmpwi 0,r4,0
beqlr beqlr
...@@ -626,14 +628,20 @@ _GLOBAL(__clear_user) ...@@ -626,14 +628,20 @@ _GLOBAL(__clear_user)
8: stbu r5,1(r6) 8: stbu r5,1(r6)
bdnz 8b bdnz 8b
blr blr
99: li r3,-EFAULT 90: mr r3,r4
blr
91: mfctr r3
slwi r3,r3,2
add r3,r3,r4
blr
92: mfctr r3
blr blr
.section __ex_table,"a" .section __ex_table,"a"
.align 2 .align 2
.long 11b,99b .long 11b,90b
.long 1b,99b .long 1b,91b
.long 8b,99b .long 8b,92b
.text .text
_GLOBAL(__strncpy_from_user) _GLOBAL(__strncpy_from_user)
......
/* /*
* BK Id: SCCS/s.uaccess.h 1.8 09/11/01 18:10:06 paulus * BK Id: %F% %I% %G% %U% %#%
*/ */
#ifdef __KERNEL__ #ifdef __KERNEL__
#ifndef _PPC_UACCESS_H #ifndef _PPC_UACCESS_H
...@@ -272,7 +272,11 @@ clear_user(void *addr, unsigned long size) ...@@ -272,7 +272,11 @@ clear_user(void *addr, unsigned long size)
{ {
if (access_ok(VERIFY_WRITE, addr, size)) if (access_ok(VERIFY_WRITE, addr, size))
return __clear_user(addr, size); return __clear_user(addr, size);
return size? -EFAULT: 0; if ((unsigned long)addr < TASK_SIZE) {
unsigned long over = (unsigned long)addr + size - TASK_SIZE;
return __clear_user(addr, size - over) + over;
}
return size;
} }
extern int __strncpy_from_user(char *dst, const char *src, long count); extern int __strncpy_from_user(char *dst, const char *src, long count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment