diff options
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 166 |
1 files changed, 13 insertions, 153 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index d3023df8477f..dfd60192bc2e 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -120,147 +120,6 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base) | |||
120 | } | 120 | } |
121 | EXPORT_SYMBOL(simple_strtoll); | 121 | EXPORT_SYMBOL(simple_strtoll); |
122 | 122 | ||
123 | /** | ||
124 | * strict_strtoul - convert a string to an unsigned long strictly | ||
125 | * @cp: The string to be converted | ||
126 | * @base: The number base to use | ||
127 | * @res: The converted result value | ||
128 | * | ||
129 | * strict_strtoul converts a string to an unsigned long only if the | ||
130 | * string is really an unsigned long string, any string containing | ||
131 | * any invalid char at the tail will be rejected and -EINVAL is returned, | ||
132 | * only a newline char at the tail is acceptible because people generally | ||
133 | * change a module parameter in the following way: | ||
134 | * | ||
135 | * echo 1024 > /sys/module/e1000/parameters/copybreak | ||
136 | * | ||
137 | * echo will append a newline to the tail. | ||
138 | * | ||
139 | * It returns 0 if conversion is successful and *res is set to the converted | ||
140 | * value, otherwise it returns -EINVAL and *res is set to 0. | ||
141 | * | ||
142 | * simple_strtoul just ignores the successive invalid characters and | ||
143 | * return the converted value of prefix part of the string. | ||
144 | */ | ||
145 | int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) | ||
146 | { | ||
147 | char *tail; | ||
148 | unsigned long val; | ||
149 | |||
150 | *res = 0; | ||
151 | if (!*cp) | ||
152 | return -EINVAL; | ||
153 | |||
154 | val = simple_strtoul(cp, &tail, base); | ||
155 | if (tail == cp) | ||
156 | return -EINVAL; | ||
157 | |||
158 | if ((tail[0] == '\0') || (tail[0] == '\n' && tail[1] == '\0')) { | ||
159 | *res = val; | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | return -EINVAL; | ||
164 | } | ||
165 | EXPORT_SYMBOL(strict_strtoul); | ||
166 | |||
167 | /** | ||
168 | * strict_strtol - convert a string to a long strictly | ||
169 | * @cp: The string to be converted | ||
170 | * @base: The number base to use | ||
171 | * @res: The converted result value | ||
172 | * | ||
173 | * strict_strtol is similiar to strict_strtoul, but it allows the first | ||
174 | * character of a string is '-'. | ||
175 | * | ||
176 | * It returns 0 if conversion is successful and *res is set to the converted | ||
177 | * value, otherwise it returns -EINVAL and *res is set to 0. | ||
178 | */ | ||
179 | int strict_strtol(const char *cp, unsigned int base, long *res) | ||
180 | { | ||
181 | int ret; | ||
182 | if (*cp == '-') { | ||
183 | ret = strict_strtoul(cp + 1, base, (unsigned long *)res); | ||
184 | if (!ret) | ||
185 | *res = -(*res); | ||
186 | } else { | ||
187 | ret = strict_strtoul(cp, base, (unsigned long *)res); | ||
188 | } | ||
189 | |||
190 | return ret; | ||
191 | } | ||
192 | EXPORT_SYMBOL(strict_strtol); | ||
193 | |||
194 | /** | ||
195 | * strict_strtoull - convert a string to an unsigned long long strictly | ||
196 | * @cp: The string to be converted | ||
197 | * @base: The number base to use | ||
198 | * @res: The converted result value | ||
199 | * | ||
200 | * strict_strtoull converts a string to an unsigned long long only if the | ||
201 | * string is really an unsigned long long string, any string containing | ||
202 | * any invalid char at the tail will be rejected and -EINVAL is returned, | ||
203 | * only a newline char at the tail is acceptible because people generally | ||
204 | * change a module parameter in the following way: | ||
205 | * | ||
206 | * echo 1024 > /sys/module/e1000/parameters/copybreak | ||
207 | * | ||
208 | * echo will append a newline to the tail of the string. | ||
209 | * | ||
210 | * It returns 0 if conversion is successful and *res is set to the converted | ||
211 | * value, otherwise it returns -EINVAL and *res is set to 0. | ||
212 | * | ||
213 | * simple_strtoull just ignores the successive invalid characters and | ||
214 | * return the converted value of prefix part of the string. | ||
215 | */ | ||
216 | int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res) | ||
217 | { | ||
218 | char *tail; | ||
219 | unsigned long long val; | ||
220 | |||
221 | *res = 0; | ||
222 | if (!*cp) | ||
223 | return -EINVAL; | ||
224 | |||
225 | val = simple_strtoull(cp, &tail, base); | ||
226 | if (tail == cp) | ||
227 | return -EINVAL; | ||
228 | if ((tail[0] == '\0') || (tail[0] == '\n' && tail[1] == '\0')) { | ||
229 | *res = val; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | return -EINVAL; | ||
234 | } | ||
235 | EXPORT_SYMBOL(strict_strtoull); | ||
236 | |||
237 | /** | ||
238 | * strict_strtoll - convert a string to a long long strictly | ||
239 | * @cp: The string to be converted | ||
240 | * @base: The number base to use | ||
241 | * @res: The converted result value | ||
242 | * | ||
243 | * strict_strtoll is similiar to strict_strtoull, but it allows the first | ||
244 | * character of a string is '-'. | ||
245 | * | ||
246 | * It returns 0 if conversion is successful and *res is set to the converted | ||
247 | * value, otherwise it returns -EINVAL and *res is set to 0. | ||
248 | */ | ||
249 | int strict_strtoll(const char *cp, unsigned int base, long long *res) | ||
250 | { | ||
251 | int ret; | ||
252 | if (*cp == '-') { | ||
253 | ret = strict_strtoull(cp + 1, base, (unsigned long long *)res); | ||
254 | if (!ret) | ||
255 | *res = -(*res); | ||
256 | } else { | ||
257 | ret = strict_strtoull(cp, base, (unsigned long long *)res); | ||
258 | } | ||
259 | |||
260 | return ret; | ||
261 | } | ||
262 | EXPORT_SYMBOL(strict_strtoll); | ||
263 | |||
264 | static noinline_for_stack | 123 | static noinline_for_stack |
265 | int skip_atoi(const char **s) | 124 | int skip_atoi(const char **s) |
266 | { | 125 | { |
@@ -574,7 +433,9 @@ char *symbol_string(char *buf, char *end, void *ptr, | |||
574 | unsigned long value = (unsigned long) ptr; | 433 | unsigned long value = (unsigned long) ptr; |
575 | #ifdef CONFIG_KALLSYMS | 434 | #ifdef CONFIG_KALLSYMS |
576 | char sym[KSYM_SYMBOL_LEN]; | 435 | char sym[KSYM_SYMBOL_LEN]; |
577 | if (ext != 'f' && ext != 's') | 436 | if (ext == 'B') |
437 | sprint_backtrace(sym, value); | ||
438 | else if (ext != 'f' && ext != 's') | ||
578 | sprint_symbol(sym, value); | 439 | sprint_symbol(sym, value); |
579 | else | 440 | else |
580 | kallsyms_lookup(value, NULL, NULL, NULL, sym); | 441 | kallsyms_lookup(value, NULL, NULL, NULL, sym); |
@@ -936,7 +797,7 @@ char *uuid_string(char *buf, char *end, const u8 *addr, | |||
936 | return string(buf, end, uuid, spec); | 797 | return string(buf, end, uuid, spec); |
937 | } | 798 | } |
938 | 799 | ||
939 | int kptr_restrict = 1; | 800 | int kptr_restrict __read_mostly; |
940 | 801 | ||
941 | /* | 802 | /* |
942 | * Show a '%p' thing. A kernel extension is that the '%p' is followed | 803 | * Show a '%p' thing. A kernel extension is that the '%p' is followed |
@@ -949,6 +810,7 @@ int kptr_restrict = 1; | |||
949 | * - 'f' For simple symbolic function names without offset | 810 | * - 'f' For simple symbolic function names without offset |
950 | * - 'S' For symbolic direct pointers with offset | 811 | * - 'S' For symbolic direct pointers with offset |
951 | * - 's' For symbolic direct pointers without offset | 812 | * - 's' For symbolic direct pointers without offset |
813 | * - 'B' For backtraced symbolic direct pointers with offset | ||
952 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] | 814 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
953 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] | 815 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] |
954 | * - 'M' For a 6-byte MAC address, it prints the address in the | 816 | * - 'M' For a 6-byte MAC address, it prints the address in the |
@@ -991,7 +853,7 @@ static noinline_for_stack | |||
991 | char *pointer(const char *fmt, char *buf, char *end, void *ptr, | 853 | char *pointer(const char *fmt, char *buf, char *end, void *ptr, |
992 | struct printf_spec spec) | 854 | struct printf_spec spec) |
993 | { | 855 | { |
994 | if (!ptr) { | 856 | if (!ptr && *fmt != 'K') { |
995 | /* | 857 | /* |
996 | * Print (null) with the same width as a pointer so it makes | 858 | * Print (null) with the same width as a pointer so it makes |
997 | * tabular output look nice. | 859 | * tabular output look nice. |
@@ -1008,6 +870,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1008 | /* Fallthrough */ | 870 | /* Fallthrough */ |
1009 | case 'S': | 871 | case 'S': |
1010 | case 's': | 872 | case 's': |
873 | case 'B': | ||
1011 | return symbol_string(buf, end, ptr, spec, *fmt); | 874 | return symbol_string(buf, end, ptr, spec, *fmt); |
1012 | case 'R': | 875 | case 'R': |
1013 | case 'r': | 876 | case 'r': |
@@ -1047,16 +910,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1047 | if (spec.field_width == -1) | 910 | if (spec.field_width == -1) |
1048 | spec.field_width = 2 * sizeof(void *); | 911 | spec.field_width = 2 * sizeof(void *); |
1049 | return string(buf, end, "pK-error", spec); | 912 | return string(buf, end, "pK-error", spec); |
1050 | } else if ((kptr_restrict == 0) || | ||
1051 | (kptr_restrict == 1 && | ||
1052 | has_capability_noaudit(current, CAP_SYSLOG))) | ||
1053 | break; | ||
1054 | |||
1055 | if (spec.field_width == -1) { | ||
1056 | spec.field_width = 2 * sizeof(void *); | ||
1057 | spec.flags |= ZEROPAD; | ||
1058 | } | 913 | } |
1059 | return number(buf, end, 0, spec); | 914 | if (!((kptr_restrict == 0) || |
915 | (kptr_restrict == 1 && | ||
916 | has_capability_noaudit(current, CAP_SYSLOG)))) | ||
917 | ptr = NULL; | ||
918 | break; | ||
1060 | } | 919 | } |
1061 | spec.flags |= SMALL; | 920 | spec.flags |= SMALL; |
1062 | if (spec.field_width == -1) { | 921 | if (spec.field_width == -1) { |
@@ -1279,6 +1138,7 @@ qualifier: | |||
1279 | * %ps output the name of a text symbol without offset | 1138 | * %ps output the name of a text symbol without offset |
1280 | * %pF output the name of a function pointer with its offset | 1139 | * %pF output the name of a function pointer with its offset |
1281 | * %pf output the name of a function pointer without its offset | 1140 | * %pf output the name of a function pointer without its offset |
1141 | * %pB output the name of a backtrace symbol with its offset | ||
1282 | * %pR output the address range in a struct resource with decoded flags | 1142 | * %pR output the address range in a struct resource with decoded flags |
1283 | * %pr output the address range in a struct resource with raw flags | 1143 | * %pr output the address range in a struct resource with raw flags |
1284 | * %pM output a 6-byte MAC address with colons | 1144 | * %pM output a 6-byte MAC address with colons |