diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-05-13 23:52:56 -0400 |
---|---|---|
committer | Paul Mundt <lethal@hera.kernel.org> | 2007-06-07 22:43:36 -0400 |
commit | e08f457c7c0cc7720f28349f8780ea752c063441 (patch) | |
tree | 7b82666f2002d57dc57d022daf90c778265159e9 | |
parent | 7a302a9674593259866de4a9d5ae8edc03dc1934 (diff) |
sh: __user annotations for __get/__put_user().
This adds in some more __user annotations. These weren't being
handled properly in some of the __get_user and __put_user paths,
so tidy those up.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/kernel/process.c | 12 | ||||
-rw-r--r-- | arch/sh/kernel/ptrace.c | 8 | ||||
-rw-r--r-- | arch/sh/kernel/signal.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/traps.c | 2 | ||||
-rw-r--r-- | include/asm-sh/page.h | 1 | ||||
-rw-r--r-- | include/asm-sh/sections.h | 2 | ||||
-rw-r--r-- | include/asm-sh/system.h | 14 | ||||
-rw-r--r-- | include/asm-sh/uaccess.h | 40 |
8 files changed, 49 insertions, 34 deletions
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index a11e2aa73cbc..aa9c8112140b 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kexec.h> | 17 | #include <linux/kexec.h> |
18 | #include <linux/kdebug.h> | 18 | #include <linux/kdebug.h> |
19 | #include <linux/tick.h> | 19 | #include <linux/tick.h> |
20 | #include <linux/reboot.h> | ||
20 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
21 | #include <asm/mmu_context.h> | 22 | #include <asm/mmu_context.h> |
22 | #include <asm/pgalloc.h> | 23 | #include <asm/pgalloc.h> |
@@ -449,23 +450,20 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, | |||
449 | /* | 450 | /* |
450 | * sys_execve() executes a new program. | 451 | * sys_execve() executes a new program. |
451 | */ | 452 | */ |
452 | asmlinkage int sys_execve(char *ufilename, char **uargv, | 453 | asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv, |
453 | char **uenvp, unsigned long r7, | 454 | char __user * __user *uenvp, unsigned long r7, |
454 | struct pt_regs __regs) | 455 | struct pt_regs __regs) |
455 | { | 456 | { |
456 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | 457 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); |
457 | int error; | 458 | int error; |
458 | char *filename; | 459 | char *filename; |
459 | 460 | ||
460 | filename = getname((char __user *)ufilename); | 461 | filename = getname(ufilename); |
461 | error = PTR_ERR(filename); | 462 | error = PTR_ERR(filename); |
462 | if (IS_ERR(filename)) | 463 | if (IS_ERR(filename)) |
463 | goto out; | 464 | goto out; |
464 | 465 | ||
465 | error = do_execve(filename, | 466 | error = do_execve(filename, uargv, uenvp, regs); |
466 | (char __user * __user *)uargv, | ||
467 | (char __user * __user *)uenvp, | ||
468 | regs); | ||
469 | if (error == 0) { | 467 | if (error == 0) { |
470 | task_lock(current); | 468 | task_lock(current); |
471 | current->ptrace &= ~PT_DTRACE; | 469 | current->ptrace &= ~PT_DTRACE; |
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index 3fb5fc0b550d..f2eaa485d04d 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c | |||
@@ -99,7 +99,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
99 | ret = -EIO; | 99 | ret = -EIO; |
100 | if (copied != sizeof(tmp)) | 100 | if (copied != sizeof(tmp)) |
101 | break; | 101 | break; |
102 | ret = put_user(tmp,(unsigned long *) data); | 102 | ret = put_user(tmp,(unsigned long __user *) data); |
103 | break; | 103 | break; |
104 | } | 104 | } |
105 | 105 | ||
@@ -128,7 +128,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
128 | tmp = !!tsk_used_math(child); | 128 | tmp = !!tsk_used_math(child); |
129 | else | 129 | else |
130 | tmp = 0; | 130 | tmp = 0; |
131 | ret = put_user(tmp, (unsigned long *)data); | 131 | ret = put_user(tmp, (unsigned long __user *)data); |
132 | break; | 132 | break; |
133 | } | 133 | } |
134 | 134 | ||
@@ -196,7 +196,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
196 | 196 | ||
197 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | 197 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ |
198 | long pc; | 198 | long pc; |
199 | struct pt_regs *dummy = NULL; | 199 | struct pt_regs *regs = NULL; |
200 | 200 | ||
201 | ret = -EIO; | 201 | ret = -EIO; |
202 | if (!valid_signal(data)) | 202 | if (!valid_signal(data)) |
@@ -207,7 +207,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
207 | child->ptrace |= PT_DTRACE; | 207 | child->ptrace |= PT_DTRACE; |
208 | } | 208 | } |
209 | 209 | ||
210 | pc = get_stack_long(child, (long)&dummy->pc); | 210 | pc = get_stack_long(child, (long)®s->pc); |
211 | 211 | ||
212 | /* Next scheduling will set up UBC */ | 212 | /* Next scheduling will set up UBC */ |
213 | if (child->thread.ubc_pc == 0) | 213 | if (child->thread.ubc_pc == 0) |
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index b32c35a7c0a3..4fc5b402b21b 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c | |||
@@ -261,14 +261,14 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, | |||
261 | goto badframe; | 261 | goto badframe; |
262 | /* It is more difficult to avoid calling this function than to | 262 | /* It is more difficult to avoid calling this function than to |
263 | call it and ignore errors. */ | 263 | call it and ignore errors. */ |
264 | do_sigaltstack(&st, NULL, regs->regs[15]); | 264 | do_sigaltstack((const stack_t __user *)&st, NULL, (unsigned long)frame); |
265 | 265 | ||
266 | return r0; | 266 | return r0; |
267 | 267 | ||
268 | badframe: | 268 | badframe: |
269 | force_sig(SIGSEGV, current); | 269 | force_sig(SIGSEGV, current); |
270 | return 0; | 270 | return 0; |
271 | } | 271 | } |
272 | 272 | ||
273 | /* | 273 | /* |
274 | * Set up a signal frame. | 274 | * Set up a signal frame. |
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 5b75cb6f8f9b..299b8cf0f512 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c | |||
@@ -581,7 +581,7 @@ uspace_segv: | |||
581 | info.si_signo = SIGBUS; | 581 | info.si_signo = SIGBUS; |
582 | info.si_errno = 0; | 582 | info.si_errno = 0; |
583 | info.si_code = si_code; | 583 | info.si_code = si_code; |
584 | info.si_addr = (void *) address; | 584 | info.si_addr = (void __user *)address; |
585 | force_sig_info(SIGBUS, &info, current); | 585 | force_sig_info(SIGBUS, &info, current); |
586 | } else { | 586 | } else { |
587 | if (regs->pc & 1) | 587 | if (regs->pc & 1) |
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 7464de4ba07d..011dfbe14a6b 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h | |||
@@ -60,6 +60,7 @@ extern void (*copy_page)(void *to, void *from); | |||
60 | 60 | ||
61 | extern unsigned long shm_align_mask; | 61 | extern unsigned long shm_align_mask; |
62 | extern unsigned long max_low_pfn, min_low_pfn; | 62 | extern unsigned long max_low_pfn, min_low_pfn; |
63 | extern unsigned long memory_start, memory_end; | ||
63 | 64 | ||
64 | #ifdef CONFIG_MMU | 65 | #ifdef CONFIG_MMU |
65 | extern void clear_page_slow(void *to); | 66 | extern void clear_page_slow(void *to); |
diff --git a/include/asm-sh/sections.h b/include/asm-sh/sections.h index 57abd708b236..44c06c09e208 100644 --- a/include/asm-sh/sections.h +++ b/include/asm-sh/sections.h | |||
@@ -3,7 +3,5 @@ | |||
3 | 3 | ||
4 | #include <asm-generic/sections.h> | 4 | #include <asm-generic/sections.h> |
5 | 5 | ||
6 | extern char _end[]; | ||
7 | |||
8 | #endif /* __ASM_SH_SECTIONS_H */ | 6 | #endif /* __ASM_SH_SECTIONS_H */ |
9 | 7 | ||
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 82f3e229e621..fb22fc3f87ad 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h | |||
@@ -8,9 +8,13 @@ | |||
8 | 8 | ||
9 | #include <linux/irqflags.h> | 9 | #include <linux/irqflags.h> |
10 | #include <linux/compiler.h> | 10 | #include <linux/compiler.h> |
11 | #include <linux/linkage.h> | ||
11 | #include <asm/types.h> | 12 | #include <asm/types.h> |
12 | #include <asm/ptrace.h> | 13 | #include <asm/ptrace.h> |
13 | 14 | ||
15 | struct task_struct *__switch_to(struct task_struct *prev, | ||
16 | struct task_struct *next); | ||
17 | |||
14 | /* | 18 | /* |
15 | * switch_to() should switch tasks to task nr n, first | 19 | * switch_to() should switch tasks to task nr n, first |
16 | */ | 20 | */ |
@@ -271,6 +275,16 @@ extern unsigned int instruction_size(unsigned int insn); | |||
271 | void disable_hlt(void); | 275 | void disable_hlt(void); |
272 | void enable_hlt(void); | 276 | void enable_hlt(void); |
273 | 277 | ||
278 | void default_idle(void); | ||
279 | |||
280 | asmlinkage void break_point_trap(void); | ||
281 | asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, | ||
282 | unsigned long r6, unsigned long r7, | ||
283 | struct pt_regs __regs); | ||
284 | asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, | ||
285 | unsigned long r6, unsigned long r7, | ||
286 | struct pt_regs __regs); | ||
287 | |||
274 | #define arch_align_stack(x) (x) | 288 | #define arch_align_stack(x) (x) |
275 | 289 | ||
276 | #endif | 290 | #endif |
diff --git a/include/asm-sh/uaccess.h b/include/asm-sh/uaccess.h index 5c49ed6715f2..f18a1a5c95c0 100644 --- a/include/asm-sh/uaccess.h +++ b/include/asm-sh/uaccess.h | |||
@@ -61,8 +61,6 @@ static inline void set_fs(mm_segment_t s) | |||
61 | */ | 61 | */ |
62 | static inline int __access_ok(unsigned long addr, unsigned long size) | 62 | static inline int __access_ok(unsigned long addr, unsigned long size) |
63 | { | 63 | { |
64 | extern unsigned long memory_start, memory_end; | ||
65 | |||
66 | return ((addr >= memory_start) && ((addr + size) < memory_end)); | 64 | return ((addr >= memory_start) && ((addr + size) < memory_end)); |
67 | } | 65 | } |
68 | #else /* CONFIG_MMU */ | 66 | #else /* CONFIG_MMU */ |
@@ -76,7 +74,7 @@ static inline int __access_ok(unsigned long addr, unsigned long size) | |||
76 | * __access_ok: Check if address with size is OK or not. | 74 | * __access_ok: Check if address with size is OK or not. |
77 | * | 75 | * |
78 | * We do three checks: | 76 | * We do three checks: |
79 | * (1) is it user space? | 77 | * (1) is it user space? |
80 | * (2) addr + size --> carry? | 78 | * (2) addr + size --> carry? |
81 | * (3) addr + size >= 0x80000000 (PAGE_OFFSET) | 79 | * (3) addr + size >= 0x80000000 (PAGE_OFFSET) |
82 | * | 80 | * |
@@ -142,11 +140,12 @@ static inline int access_ok(int type, const void __user *p, unsigned long size) | |||
142 | __get_user_nocheck((x),(ptr),sizeof(*(ptr))) | 140 | __get_user_nocheck((x),(ptr),sizeof(*(ptr))) |
143 | 141 | ||
144 | struct __large_struct { unsigned long buf[100]; }; | 142 | struct __large_struct { unsigned long buf[100]; }; |
145 | #define __m(x) (*(struct __large_struct *)(x)) | 143 | #define __m(x) (*(struct __large_struct __user *)(x)) |
146 | 144 | ||
147 | #define __get_user_size(x,ptr,size,retval) \ | 145 | #define __get_user_size(x,ptr,size,retval) \ |
148 | do { \ | 146 | do { \ |
149 | retval = 0; \ | 147 | retval = 0; \ |
148 | __chk_user_ptr(ptr); \ | ||
150 | switch (size) { \ | 149 | switch (size) { \ |
151 | case 1: \ | 150 | case 1: \ |
152 | __get_user_asm(x, ptr, retval, "b"); \ | 151 | __get_user_asm(x, ptr, retval, "b"); \ |
@@ -175,6 +174,7 @@ do { \ | |||
175 | #define __get_user_check(x,ptr,size) \ | 174 | #define __get_user_check(x,ptr,size) \ |
176 | ({ \ | 175 | ({ \ |
177 | long __gu_err, __gu_val; \ | 176 | long __gu_err, __gu_val; \ |
177 | __chk_user_ptr(ptr); \ | ||
178 | switch (size) { \ | 178 | switch (size) { \ |
179 | case 1: \ | 179 | case 1: \ |
180 | __get_user_1(__gu_val, (ptr), __gu_err); \ | 180 | __get_user_1(__gu_val, (ptr), __gu_err); \ |
@@ -300,6 +300,7 @@ extern void __get_user_unknown(void); | |||
300 | #define __put_user_size(x,ptr,size,retval) \ | 300 | #define __put_user_size(x,ptr,size,retval) \ |
301 | do { \ | 301 | do { \ |
302 | retval = 0; \ | 302 | retval = 0; \ |
303 | __chk_user_ptr(ptr); \ | ||
303 | switch (size) { \ | 304 | switch (size) { \ |
304 | case 1: \ | 305 | case 1: \ |
305 | __put_user_asm(x, ptr, retval, "b"); \ | 306 | __put_user_asm(x, ptr, retval, "b"); \ |
@@ -328,7 +329,7 @@ do { \ | |||
328 | #define __put_user_check(x,ptr,size) \ | 329 | #define __put_user_check(x,ptr,size) \ |
329 | ({ \ | 330 | ({ \ |
330 | long __pu_err = -EFAULT; \ | 331 | long __pu_err = -EFAULT; \ |
331 | __typeof__(*(ptr)) *__pu_addr = (ptr); \ | 332 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ |
332 | \ | 333 | \ |
333 | if (__access_ok((unsigned long)__pu_addr,size)) \ | 334 | if (__access_ok((unsigned long)__pu_addr,size)) \ |
334 | __put_user_size((x),__pu_addr,(size),__pu_err); \ | 335 | __put_user_size((x),__pu_addr,(size),__pu_err); \ |
@@ -406,10 +407,10 @@ __asm__ __volatile__( \ | |||
406 | #endif | 407 | #endif |
407 | 408 | ||
408 | extern void __put_user_unknown(void); | 409 | extern void __put_user_unknown(void); |
409 | 410 | ||
410 | /* Generic arbitrary sized copy. */ | 411 | /* Generic arbitrary sized copy. */ |
411 | /* Return the number of bytes NOT copied */ | 412 | /* Return the number of bytes NOT copied */ |
412 | extern __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); | 413 | __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); |
413 | 414 | ||
414 | #define copy_to_user(to,from,n) ({ \ | 415 | #define copy_to_user(to,from,n) ({ \ |
415 | void *__copy_to = (void *) (to); \ | 416 | void *__copy_to = (void *) (to); \ |
@@ -420,14 +421,6 @@ __copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \ | |||
420 | } else __copy_res = __copy_size; \ | 421 | } else __copy_res = __copy_size; \ |
421 | __copy_res; }) | 422 | __copy_res; }) |
422 | 423 | ||
423 | #define __copy_to_user(to,from,n) \ | ||
424 | __copy_user((void *)(to), \ | ||
425 | (void *)(from), n) | ||
426 | |||
427 | #define __copy_to_user_inatomic __copy_to_user | ||
428 | #define __copy_from_user_inatomic __copy_from_user | ||
429 | |||
430 | |||
431 | #define copy_from_user(to,from,n) ({ \ | 424 | #define copy_from_user(to,from,n) ({ \ |
432 | void *__copy_to = (void *) (to); \ | 425 | void *__copy_to = (void *) (to); \ |
433 | void *__copy_from = (void *) (from); \ | 426 | void *__copy_from = (void *) (from); \ |
@@ -438,9 +431,20 @@ __copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \ | |||
438 | } else __copy_res = __copy_size; \ | 431 | } else __copy_res = __copy_size; \ |
439 | __copy_res; }) | 432 | __copy_res; }) |
440 | 433 | ||
441 | #define __copy_from_user(to,from,n) \ | 434 | static __always_inline unsigned long |
442 | __copy_user((void *)(to), \ | 435 | __copy_from_user(void *to, const void __user *from, unsigned long n) |
443 | (void *)(from), n) | 436 | { |
437 | return __copy_user(to, (__force void *)from, n); | ||
438 | } | ||
439 | |||
440 | static __always_inline unsigned long __must_check | ||
441 | __copy_to_user(void __user *to, const void *from, unsigned long n) | ||
442 | { | ||
443 | return __copy_user((__force void *)to, from, n); | ||
444 | } | ||
445 | |||
446 | #define __copy_to_user_inatomic __copy_to_user | ||
447 | #define __copy_from_user_inatomic __copy_from_user | ||
444 | 448 | ||
445 | /* | 449 | /* |
446 | * Clear the area and return remaining number of bytes | 450 | * Clear the area and return remaining number of bytes |