aboutsummaryrefslogtreecommitdiffstats
path: root/lib/vsprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r--lib/vsprintf.c166
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}
121EXPORT_SYMBOL(simple_strtoll); 121EXPORT_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 */
145int 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}
165EXPORT_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 */
179int 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}
192EXPORT_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 */
216int 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}
235EXPORT_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 */
249int 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}
262EXPORT_SYMBOL(strict_strtoll);
263
264static noinline_for_stack 123static noinline_for_stack
265int skip_atoi(const char **s) 124int 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
939int kptr_restrict = 1; 800int 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
991char *pointer(const char *fmt, char *buf, char *end, void *ptr, 853char *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