diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/uaccess.h | 27 | ||||
-rw-r--r-- | arch/arm/include/asm/word-at-a-time.h | 55 | ||||
-rw-r--r-- | arch/arm/kernel/armksyms.c | 4 | ||||
-rw-r--r-- | arch/arm/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/lib/strncpy_from_user.S | 43 | ||||
-rw-r--r-- | arch/arm/lib/strnlen_user.S | 40 |
7 files changed, 63 insertions, 109 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8c9d264f2108..574561a66d75 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -46,6 +46,8 @@ config ARM | |||
46 | select GENERIC_SMP_IDLE_THREAD | 46 | select GENERIC_SMP_IDLE_THREAD |
47 | select KTIME_SCALAR | 47 | select KTIME_SCALAR |
48 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP | 48 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP |
49 | select GENERIC_STRNCPY_FROM_USER | ||
50 | select GENERIC_STRNLEN_USER | ||
49 | help | 51 | help |
50 | The ARM series is a line of low-power-consumption RISC chip designs | 52 | The ARM series is a line of low-power-consumption RISC chip designs |
51 | licensed by ARM Ltd and targeted at embedded applications and | 53 | licensed by ARM Ltd and targeted at embedded applications and |
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 71f6536d17ac..479a6352e0b5 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
@@ -189,6 +189,9 @@ static inline void set_fs(mm_segment_t fs) | |||
189 | 189 | ||
190 | #define access_ok(type,addr,size) (__range_ok(addr,size) == 0) | 190 | #define access_ok(type,addr,size) (__range_ok(addr,size) == 0) |
191 | 191 | ||
192 | #define user_addr_max() \ | ||
193 | (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) | ||
194 | |||
192 | /* | 195 | /* |
193 | * The "__xxx" versions of the user access functions do not verify the | 196 | * The "__xxx" versions of the user access functions do not verify the |
194 | * address space - it must have been done previously with a separate | 197 | * address space - it must have been done previously with a separate |
@@ -398,9 +401,6 @@ extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned l | |||
398 | #define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0) | 401 | #define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0) |
399 | #endif | 402 | #endif |
400 | 403 | ||
401 | extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count); | ||
402 | extern unsigned long __must_check __strnlen_user(const char __user *s, long n); | ||
403 | |||
404 | static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) | 404 | static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) |
405 | { | 405 | { |
406 | if (access_ok(VERIFY_READ, from, n)) | 406 | if (access_ok(VERIFY_READ, from, n)) |
@@ -427,24 +427,9 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo | |||
427 | return n; | 427 | return n; |
428 | } | 428 | } |
429 | 429 | ||
430 | static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) | 430 | extern long strncpy_from_user(char *dest, const char __user *src, long count); |
431 | { | ||
432 | long res = -EFAULT; | ||
433 | if (access_ok(VERIFY_READ, src, 1)) | ||
434 | res = __strncpy_from_user(dst, src, count); | ||
435 | return res; | ||
436 | } | ||
437 | |||
438 | #define strlen_user(s) strnlen_user(s, ~0UL >> 1) | ||
439 | 431 | ||
440 | static inline long __must_check strnlen_user(const char __user *s, long n) | 432 | extern __must_check long strlen_user(const char __user *str); |
441 | { | 433 | extern __must_check long strnlen_user(const char __user *str, long n); |
442 | unsigned long res = 0; | ||
443 | |||
444 | if (__addr_ok(s)) | ||
445 | res = __strnlen_user(s, n); | ||
446 | |||
447 | return res; | ||
448 | } | ||
449 | 434 | ||
450 | #endif /* _ASMARM_UACCESS_H */ | 435 | #endif /* _ASMARM_UACCESS_H */ |
diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h new file mode 100644 index 000000000000..74b2d4578577 --- /dev/null +++ b/arch/arm/include/asm/word-at-a-time.h | |||
@@ -0,0 +1,55 @@ | |||
1 | #ifndef __ASM_ARM_WORD_AT_A_TIME_H | ||
2 | #define __ASM_ARM_WORD_AT_A_TIME_H | ||
3 | |||
4 | #ifndef __ARMEB__ | ||
5 | |||
6 | /* | ||
7 | * Little-endian word-at-a-time zero byte handling. | ||
8 | * Heavily based on the x86 algorithm. | ||
9 | */ | ||
10 | #include <linux/kernel.h> | ||
11 | |||
12 | struct word_at_a_time { | ||
13 | const unsigned long one_bits, high_bits; | ||
14 | }; | ||
15 | |||
16 | #define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } | ||
17 | |||
18 | static inline unsigned long has_zero(unsigned long a, unsigned long *bits, | ||
19 | const struct word_at_a_time *c) | ||
20 | { | ||
21 | unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits; | ||
22 | *bits = mask; | ||
23 | return mask; | ||
24 | } | ||
25 | |||
26 | #define prep_zero_mask(a, bits, c) (bits) | ||
27 | |||
28 | static inline unsigned long create_zero_mask(unsigned long bits) | ||
29 | { | ||
30 | bits = (bits - 1) & ~bits; | ||
31 | return bits >> 7; | ||
32 | } | ||
33 | |||
34 | static inline unsigned long find_zero(unsigned long mask) | ||
35 | { | ||
36 | unsigned long ret; | ||
37 | |||
38 | #if __LINUX_ARM_ARCH__ >= 5 | ||
39 | /* We have clz available. */ | ||
40 | ret = fls(mask) >> 3; | ||
41 | #else | ||
42 | /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ | ||
43 | ret = (0x0ff0001 + mask) >> 23; | ||
44 | /* Fix the 1 for 00 case */ | ||
45 | ret &= mask; | ||
46 | #endif | ||
47 | |||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | #else /* __ARMEB__ */ | ||
52 | #include <asm-generic/word-at-a-time.h> | ||
53 | #endif | ||
54 | |||
55 | #endif /* __ASM_ARM_WORD_AT_A_TIME_H */ | ||
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index b57c75e0b01f..c3dff6abc89d 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -87,10 +87,6 @@ EXPORT_SYMBOL(memmove); | |||
87 | EXPORT_SYMBOL(memchr); | 87 | EXPORT_SYMBOL(memchr); |
88 | EXPORT_SYMBOL(__memzero); | 88 | EXPORT_SYMBOL(__memzero); |
89 | 89 | ||
90 | /* user mem (segment) */ | ||
91 | EXPORT_SYMBOL(__strnlen_user); | ||
92 | EXPORT_SYMBOL(__strncpy_from_user); | ||
93 | |||
94 | #ifdef CONFIG_MMU | 90 | #ifdef CONFIG_MMU |
95 | EXPORT_SYMBOL(copy_page); | 91 | EXPORT_SYMBOL(copy_page); |
96 | 92 | ||
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 992769ae2599..d5060dab6e52 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile | |||
@@ -8,7 +8,6 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ | |||
8 | csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ | 8 | csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ |
9 | delay.o findbit.o memchr.o memcpy.o \ | 9 | delay.o findbit.o memchr.o memcpy.o \ |
10 | memmove.o memset.o memzero.o setbit.o \ | 10 | memmove.o memset.o memzero.o setbit.o \ |
11 | strncpy_from_user.o strnlen_user.o \ | ||
12 | strchr.o strrchr.o \ | 11 | strchr.o strrchr.o \ |
13 | testchangebit.o testclearbit.o testsetbit.o \ | 12 | testchangebit.o testclearbit.o testsetbit.o \ |
14 | ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ | 13 | ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ |
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S deleted file mode 100644 index f202d7bd1647..000000000000 --- a/arch/arm/lib/strncpy_from_user.S +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/strncpy_from_user.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2000 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/linkage.h> | ||
11 | #include <asm/assembler.h> | ||
12 | #include <asm/errno.h> | ||
13 | |||
14 | .text | ||
15 | .align 5 | ||
16 | |||
17 | /* | ||
18 | * Copy a string from user space to kernel space. | ||
19 | * r0 = dst, r1 = src, r2 = byte length | ||
20 | * returns the number of characters copied (strlen of copied string), | ||
21 | * -EFAULT on exception, or "len" if we fill the whole buffer | ||
22 | */ | ||
23 | ENTRY(__strncpy_from_user) | ||
24 | mov ip, r1 | ||
25 | 1: subs r2, r2, #1 | ||
26 | ldrusr r3, r1, 1, pl | ||
27 | bmi 2f | ||
28 | strb r3, [r0], #1 | ||
29 | teq r3, #0 | ||
30 | bne 1b | ||
31 | sub r1, r1, #1 @ take NUL character out of count | ||
32 | 2: sub r0, r1, ip | ||
33 | mov pc, lr | ||
34 | ENDPROC(__strncpy_from_user) | ||
35 | |||
36 | .pushsection .fixup,"ax" | ||
37 | .align 0 | ||
38 | 9001: mov r3, #0 | ||
39 | strb r3, [r0, #0] @ null terminate | ||
40 | mov r0, #-EFAULT | ||
41 | mov pc, lr | ||
42 | .popsection | ||
43 | |||
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S deleted file mode 100644 index 0ecbb459c4f1..000000000000 --- a/arch/arm/lib/strnlen_user.S +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/strnlen_user.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2000 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/linkage.h> | ||
11 | #include <asm/assembler.h> | ||
12 | #include <asm/errno.h> | ||
13 | |||
14 | .text | ||
15 | .align 5 | ||
16 | |||
17 | /* Prototype: unsigned long __strnlen_user(const char *str, long n) | ||
18 | * Purpose : get length of a string in user memory | ||
19 | * Params : str - address of string in user memory | ||
20 | * Returns : length of string *including terminator* | ||
21 | * or zero on exception, or n + 1 if too long | ||
22 | */ | ||
23 | ENTRY(__strnlen_user) | ||
24 | mov r2, r0 | ||
25 | 1: | ||
26 | ldrusr r3, r0, 1 | ||
27 | teq r3, #0 | ||
28 | beq 2f | ||
29 | subs r1, r1, #1 | ||
30 | bne 1b | ||
31 | add r0, r0, #1 | ||
32 | 2: sub r0, r0, r2 | ||
33 | mov pc, lr | ||
34 | ENDPROC(__strnlen_user) | ||
35 | |||
36 | .pushsection .fixup,"ax" | ||
37 | .align 0 | ||
38 | 9001: mov r0, #0 | ||
39 | mov pc, lr | ||
40 | .popsection | ||