Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
lib
strncpy_from_user.c
Go to the documentation of this file.
1
#include <linux/module.h>
2
#include <
linux/uaccess.h
>
3
#include <linux/kernel.h>
4
#include <linux/errno.h>
5
6
#include <asm/byteorder.h>
7
#include <asm/word-at-a-time.h>
8
9
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
10
#define IS_UNALIGNED(src, dst) 0
11
#else
12
#define IS_UNALIGNED(src, dst) \
13
(((long) dst | (long) src) & (sizeof(long) - 1))
14
#endif
15
16
/*
17
* Do a strncpy, return length of string without final '\0'.
18
* 'count' is the user-supplied count (return 'count' if we
19
* hit it), 'max' is the address space maximum (and we return
20
* -EFAULT if we hit it).
21
*/
22
static
inline
long
do_strncpy_from_user(
char
*
dst
,
const
char
__user *
src
,
long
count
,
unsigned
long
max
)
23
{
24
const
struct
word_at_a_time
constants =
WORD_AT_A_TIME_CONSTANTS
;
25
long
res
= 0;
26
27
/*
28
* Truncate 'max' to the user-specified limit, so that
29
* we only have one limit we need to check in the loop
30
*/
31
if
(max > count)
32
max =
count
;
33
34
if
(
IS_UNALIGNED
(src, dst))
35
goto
byte_at_a_time;
36
37
while
(max >=
sizeof
(
unsigned
long
)) {
38
unsigned
long
c
,
data
;
39
40
/* Fall back to byte-at-a-time if we get a page fault */
41
if
(
unlikely
(
__get_user
(c,(
unsigned
long
__user
*)(src+res))))
42
break
;
43
*(
unsigned
long
*)(dst+res) =
c
;
44
if
(has_zero(c, &data, &constants)) {
45
data =
prep_zero_mask
(c, data, &constants);
46
data =
create_zero_mask
(data);
47
return
res + find_zero(data);
48
}
49
res +=
sizeof
(
unsigned
long
);
50
max -=
sizeof
(
unsigned
long
);
51
}
52
53
byte_at_a_time:
54
while
(max) {
55
char
c
;
56
57
if
(
unlikely
(
__get_user
(c,src+res)))
58
return
-
EFAULT
;
59
dst[
res
] =
c
;
60
if
(!c)
61
return
res
;
62
res++;
63
max--;
64
}
65
66
/*
67
* Uhhuh. We hit 'max'. But was that the user-specified maximum
68
* too? If so, that's ok - we got as much as the user asked for.
69
*/
70
if
(res >= count)
71
return
res
;
72
73
/*
74
* Nope: we hit the address space limit, and we still had more
75
* characters the caller would have wanted. That's an EFAULT.
76
*/
77
return
-
EFAULT
;
78
}
79
98
long
strncpy_from_user
(
char
*
dst
,
const
char
__user *
src
,
long
count
)
99
{
100
unsigned
long
max_addr,
src_addr
;
101
102
if
(
unlikely
(count <= 0))
103
return
0;
104
105
max_addr =
user_addr_max
();
106
src_addr = (
unsigned
long
)src;
107
if
(
likely
(src_addr < max_addr)) {
108
unsigned
long
max
= max_addr -
src_addr
;
109
return
do_strncpy_from_user(dst, src, count, max);
110
}
111
return
-
EFAULT
;
112
}
113
EXPORT_SYMBOL
(
strncpy_from_user
);
Generated on Thu Jan 10 2013 14:55:54 for Linux Kernel by
1.8.2