This source file includes following definitions.
- do_strnlen_user
- strnlen_user
1
2 #include <linux/kernel.h>
3 #include <linux/export.h>
4 #include <linux/uaccess.h>
5 #include <linux/mm.h>
6 #include <linux/bitops.h>
7
8 #include <asm/word-at-a-time.h>
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max)
24 {
25 const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
26 unsigned long align, res = 0;
27 unsigned long c;
28
29
30
31
32
33 align = (sizeof(unsigned long) - 1) & (unsigned long)src;
34 src -= align;
35 max += align;
36
37 unsafe_get_user(c, (unsigned long __user *)src, efault);
38 c |= aligned_byte_mask(align);
39
40 for (;;) {
41 unsigned long data;
42 if (has_zero(c, &data, &constants)) {
43 data = prep_zero_mask(c, data, &constants);
44 data = create_zero_mask(data);
45 return res + find_zero(data) + 1 - align;
46 }
47 res += sizeof(unsigned long);
48
49 if (unlikely(max <= sizeof(unsigned long)))
50 break;
51 max -= sizeof(unsigned long);
52 unsafe_get_user(c, (unsigned long __user *)(src+res), efault);
53 }
54 res -= align;
55
56
57
58
59
60 if (res >= count)
61 return count+1;
62
63
64
65
66
67 efault:
68 return 0;
69 }
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 long strnlen_user(const char __user *str, long count)
93 {
94 unsigned long max_addr, src_addr;
95
96 if (unlikely(count <= 0))
97 return 0;
98
99 max_addr = user_addr_max();
100 src_addr = (unsigned long)untagged_addr(str);
101 if (likely(src_addr < max_addr)) {
102 unsigned long max = max_addr - src_addr;
103 long retval;
104
105
106
107
108
109 if (max > count)
110 max = count;
111
112 if (user_access_begin(str, max)) {
113 retval = do_strnlen_user(str, count, max);
114 user_access_end();
115 return retval;
116 }
117 }
118 return 0;
119 }
120 EXPORT_SYMBOL(strnlen_user);