diff options
Diffstat (limited to 'arch/frv/kernel/uaccess.c')
-rw-r--r-- | arch/frv/kernel/uaccess.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/arch/frv/kernel/uaccess.c b/arch/frv/kernel/uaccess.c new file mode 100644 index 000000000000..f3fd58a5bc4a --- /dev/null +++ b/arch/frv/kernel/uaccess.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* uaccess.c: userspace access functions | ||
2 | * | ||
3 | * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/mm.h> | ||
13 | #include <asm/uaccess.h> | ||
14 | |||
15 | /*****************************************************************************/ | ||
16 | /* | ||
17 | * copy a null terminated string from userspace | ||
18 | */ | ||
19 | long strncpy_from_user(char *dst, const char *src, long count) | ||
20 | { | ||
21 | unsigned long max; | ||
22 | char *p, ch; | ||
23 | long err = -EFAULT; | ||
24 | |||
25 | if (count < 0) | ||
26 | BUG(); | ||
27 | |||
28 | p = dst; | ||
29 | |||
30 | #ifndef CONFIG_MMU | ||
31 | if ((unsigned long) src < memory_start) | ||
32 | goto error; | ||
33 | #endif | ||
34 | |||
35 | if ((unsigned long) src >= get_addr_limit()) | ||
36 | goto error; | ||
37 | |||
38 | max = get_addr_limit() - (unsigned long) src; | ||
39 | if ((unsigned long) count > max) { | ||
40 | memset(dst + max, 0, count - max); | ||
41 | count = max; | ||
42 | } | ||
43 | |||
44 | err = 0; | ||
45 | for (; count > 0; count--, p++, src++) { | ||
46 | __get_user_asm(err, ch, src, "ub", "=r"); | ||
47 | if (err < 0) | ||
48 | goto error; | ||
49 | if (!ch) | ||
50 | break; | ||
51 | *p = ch; | ||
52 | } | ||
53 | |||
54 | err = p - dst; /* return length excluding NUL */ | ||
55 | |||
56 | error: | ||
57 | if (count > 0) | ||
58 | memset(p, 0, count); /* clear remainder of buffer [security] */ | ||
59 | |||
60 | return err; | ||
61 | } /* end strncpy_from_user() */ | ||
62 | |||
63 | /*****************************************************************************/ | ||
64 | /* | ||
65 | * Return the size of a string (including the ending 0) | ||
66 | * | ||
67 | * Return 0 on exception, a value greater than N if too long | ||
68 | */ | ||
69 | long strnlen_user(const char *src, long count) | ||
70 | { | ||
71 | const char *p; | ||
72 | long err = 0; | ||
73 | char ch; | ||
74 | |||
75 | if (count < 0) | ||
76 | BUG(); | ||
77 | |||
78 | #ifndef CONFIG_MMU | ||
79 | if ((unsigned long) src < memory_start) | ||
80 | return 0; | ||
81 | #endif | ||
82 | |||
83 | if ((unsigned long) src >= get_addr_limit()) | ||
84 | return 0; | ||
85 | |||
86 | for (p = src; count > 0; count--, p++) { | ||
87 | __get_user_asm(err, ch, p, "ub", "=r"); | ||
88 | if (err < 0) | ||
89 | return 0; | ||
90 | if (!ch) | ||
91 | break; | ||
92 | } | ||
93 | |||
94 | return p - src + 1; /* return length including NUL */ | ||
95 | } /* end strnlen_user() */ | ||