blob: b16ee85aaf8728406d7335cee09723db15d73298 [file] [log] [blame]
James Bottomley3c9f3682008-08-31 10:13:54 -05001/*
2 * Helpers for formatting and printing strings
3 *
4 * Copyright 31 August 2008 James Bottomley
Andy Shevchenko16c7fa02013-04-30 15:27:30 -07005 * Copyright (C) 2013, Intel Corporation
James Bottomley3c9f3682008-08-31 10:13:54 -05006 */
James Bottomleyb9f28d82015-03-05 18:47:01 -08007#include <linux/bug.h>
James Bottomley3c9f3682008-08-31 10:13:54 -05008#include <linux/kernel.h>
9#include <linux/math64.h>
Paul Gortmaker8bc3bcc2011-11-16 21:29:17 -050010#include <linux/export.h>
Andy Shevchenko16c7fa02013-04-30 15:27:30 -070011#include <linux/ctype.h>
Andy Shevchenkoc8250382014-10-13 15:55:16 -070012#include <linux/errno.h>
Kees Cook0d044322016-04-20 15:46:24 -070013#include <linux/mm.h>
Kees Cookb53f27e2016-04-20 15:46:23 -070014#include <linux/slab.h>
Andy Shevchenkoc8250382014-10-13 15:55:16 -070015#include <linux/string.h>
James Bottomley3c9f3682008-08-31 10:13:54 -050016#include <linux/string_helpers.h>
17
18/**
19 * string_get_size - get the size in the specified units
James Bottomleyb9f28d82015-03-05 18:47:01 -080020 * @size: The size to be converted in blocks
21 * @blk_size: Size of the block (use 1 for size in bytes)
James Bottomley3c9f3682008-08-31 10:13:54 -050022 * @units: units to use (powers of 1000 or 1024)
23 * @buf: buffer to format to
24 * @len: length of buffer
25 *
26 * This function returns a string formatted to 3 significant figures
Rasmus Villemoesd1214c62015-02-12 15:01:50 -080027 * giving the size in the required units. @buf should have room for
28 * at least 9 bytes and will always be zero terminated.
James Bottomley3c9f3682008-08-31 10:13:54 -050029 *
30 */
James Bottomleyb9f28d82015-03-05 18:47:01 -080031void string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
Rasmus Villemoesd1214c62015-02-12 15:01:50 -080032 char *buf, int len)
James Bottomley3c9f3682008-08-31 10:13:54 -050033{
Mathias Krause142cda52014-08-06 16:09:31 -070034 static const char *const units_10[] = {
James Bottomleyb9f28d82015-03-05 18:47:01 -080035 "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
Mathias Krause142cda52014-08-06 16:09:31 -070036 };
37 static const char *const units_2[] = {
James Bottomleyb9f28d82015-03-05 18:47:01 -080038 "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
Mathias Krause142cda52014-08-06 16:09:31 -070039 };
40 static const char *const *const units_str[] = {
41 [STRING_UNITS_10] = units_10,
James Bottomley3c9f3682008-08-31 10:13:54 -050042 [STRING_UNITS_2] = units_2,
43 };
Andrew Morton68aecfb2012-05-29 15:07:32 -070044 static const unsigned int divisor[] = {
James Bottomley3c9f3682008-08-31 10:13:54 -050045 [STRING_UNITS_10] = 1000,
46 [STRING_UNITS_2] = 1024,
47 };
James Bottomley564b0262016-01-20 14:58:29 -080048 static const unsigned int rounding[] = { 500, 50, 5 };
49 int i = 0, j;
50 u32 remainder = 0, sf_cap;
James Bottomley3c9f3682008-08-31 10:13:54 -050051 char tmp[8];
James Bottomleyb9f28d82015-03-05 18:47:01 -080052 const char *unit;
James Bottomley3c9f3682008-08-31 10:13:54 -050053
54 tmp[0] = '\0';
James Bottomley564b0262016-01-20 14:58:29 -080055
56 if (blk_size == 0)
57 size = 0;
58 if (size == 0)
James Bottomleyb9f28d82015-03-05 18:47:01 -080059 goto out;
James Bottomley3c9f3682008-08-31 10:13:54 -050060
James Bottomley564b0262016-01-20 14:58:29 -080061 /* This is Napier's algorithm. Reduce the original block size to
62 *
63 * coefficient * divisor[units]^i
64 *
65 * we do the reduction so both coefficients are just under 32 bits so
66 * that multiplying them together won't overflow 64 bits and we keep
67 * as much precision as possible in the numbers.
68 *
69 * Note: it's safe to throw away the remainders here because all the
70 * precision is in the coefficients.
Vitaly Kuznetsov62bef582015-09-17 16:01:51 -070071 */
James Bottomley564b0262016-01-20 14:58:29 -080072 while (blk_size >> 32) {
73 do_div(blk_size, divisor[units]);
James Bottomleyb9f28d82015-03-05 18:47:01 -080074 i++;
James Bottomleyb9f28d82015-03-05 18:47:01 -080075 }
76
James Bottomley564b0262016-01-20 14:58:29 -080077 while (size >> 32) {
78 do_div(size, divisor[units]);
79 i++;
80 }
James Bottomleyb9f28d82015-03-05 18:47:01 -080081
James Bottomley564b0262016-01-20 14:58:29 -080082 /* now perform the actual multiplication keeping i as the sum of the
83 * two logarithms */
84 size *= blk_size;
85
86 /* and logarithmically reduce it until it's just under the divisor */
James Bottomleyb9f28d82015-03-05 18:47:01 -080087 while (size >= divisor[units]) {
88 remainder = do_div(size, divisor[units]);
89 i++;
90 }
91
James Bottomley564b0262016-01-20 14:58:29 -080092 /* work out in j how many digits of precision we need from the
93 * remainder */
James Bottomleyb9f28d82015-03-05 18:47:01 -080094 sf_cap = size;
95 for (j = 0; sf_cap*10 < 1000; j++)
96 sf_cap *= 10;
97
James Bottomley564b0262016-01-20 14:58:29 -080098 if (units == STRING_UNITS_2) {
99 /* express the remainder as a decimal. It's currently the
100 * numerator of a fraction whose denominator is
101 * divisor[units], which is 1 << 10 for STRING_UNITS_2 */
James Bottomleyb9f28d82015-03-05 18:47:01 -0800102 remainder *= 1000;
James Bottomley564b0262016-01-20 14:58:29 -0800103 remainder >>= 10;
104 }
105
106 /* add a 5 to the digit below what will be printed to ensure
107 * an arithmetical round up and carry it through to size */
108 remainder += rounding[j];
109 if (remainder >= 1000) {
110 remainder -= 1000;
111 size += 1;
112 }
113
114 if (j) {
James Bottomleyb9f28d82015-03-05 18:47:01 -0800115 snprintf(tmp, sizeof(tmp), ".%03u", remainder);
116 tmp[j+1] = '\0';
117 }
118
119 out:
120 if (i >= ARRAY_SIZE(units_2))
121 unit = "UNK";
122 else
123 unit = units_str[units][i];
124
Rasmus Villemoes84b9fbe2015-02-12 15:01:48 -0800125 snprintf(buf, len, "%u%s %s", (u32)size,
James Bottomleyb9f28d82015-03-05 18:47:01 -0800126 tmp, unit);
James Bottomley3c9f3682008-08-31 10:13:54 -0500127}
128EXPORT_SYMBOL(string_get_size);
Andy Shevchenko16c7fa02013-04-30 15:27:30 -0700129
130static bool unescape_space(char **src, char **dst)
131{
132 char *p = *dst, *q = *src;
133
134 switch (*q) {
135 case 'n':
136 *p = '\n';
137 break;
138 case 'r':
139 *p = '\r';
140 break;
141 case 't':
142 *p = '\t';
143 break;
144 case 'v':
145 *p = '\v';
146 break;
147 case 'f':
148 *p = '\f';
149 break;
150 default:
151 return false;
152 }
153 *dst += 1;
154 *src += 1;
155 return true;
156}
157
158static bool unescape_octal(char **src, char **dst)
159{
160 char *p = *dst, *q = *src;
161 u8 num;
162
163 if (isodigit(*q) == 0)
164 return false;
165
166 num = (*q++) & 7;
167 while (num < 32 && isodigit(*q) && (q - *src < 3)) {
168 num <<= 3;
169 num += (*q++) & 7;
170 }
171 *p = num;
172 *dst += 1;
173 *src = q;
174 return true;
175}
176
177static bool unescape_hex(char **src, char **dst)
178{
179 char *p = *dst, *q = *src;
180 int digit;
181 u8 num;
182
183 if (*q++ != 'x')
184 return false;
185
186 num = digit = hex_to_bin(*q++);
187 if (digit < 0)
188 return false;
189
190 digit = hex_to_bin(*q);
191 if (digit >= 0) {
192 q++;
193 num = (num << 4) | digit;
194 }
195 *p = num;
196 *dst += 1;
197 *src = q;
198 return true;
199}
200
201static bool unescape_special(char **src, char **dst)
202{
203 char *p = *dst, *q = *src;
204
205 switch (*q) {
206 case '\"':
207 *p = '\"';
208 break;
209 case '\\':
210 *p = '\\';
211 break;
212 case 'a':
213 *p = '\a';
214 break;
215 case 'e':
216 *p = '\e';
217 break;
218 default:
219 return false;
220 }
221 *dst += 1;
222 *src += 1;
223 return true;
224}
225
Andy Shevchenkod2956342014-10-13 15:55:11 -0700226/**
227 * string_unescape - unquote characters in the given string
228 * @src: source buffer (escaped)
229 * @dst: destination buffer (unescaped)
230 * @size: size of the destination buffer (0 to unlimit)
231 * @flags: combination of the flags (bitwise OR):
232 * %UNESCAPE_SPACE:
233 * '\f' - form feed
234 * '\n' - new line
235 * '\r' - carriage return
236 * '\t' - horizontal tab
237 * '\v' - vertical tab
238 * %UNESCAPE_OCTAL:
239 * '\NNN' - byte with octal value NNN (1 to 3 digits)
240 * %UNESCAPE_HEX:
241 * '\xHH' - byte with hexadecimal value HH (1 to 2 digits)
242 * %UNESCAPE_SPECIAL:
243 * '\"' - double quote
244 * '\\' - backslash
245 * '\a' - alert (BEL)
246 * '\e' - escape
247 * %UNESCAPE_ANY:
248 * all previous together
249 *
250 * Description:
251 * The function unquotes characters in the given string.
252 *
253 * Because the size of the output will be the same as or less than the size of
254 * the input, the transformation may be performed in place.
255 *
256 * Caller must provide valid source and destination pointers. Be aware that
257 * destination buffer will always be NULL-terminated. Source string must be
258 * NULL-terminated as well.
259 *
260 * Return:
261 * The amount of the characters processed to the destination buffer excluding
262 * trailing '\0' is returned.
263 */
Andy Shevchenko16c7fa02013-04-30 15:27:30 -0700264int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
265{
266 char *out = dst;
267
268 while (*src && --size) {
269 if (src[0] == '\\' && src[1] != '\0' && size > 1) {
270 src++;
271 size--;
272
273 if (flags & UNESCAPE_SPACE &&
274 unescape_space(&src, &out))
275 continue;
276
277 if (flags & UNESCAPE_OCTAL &&
278 unescape_octal(&src, &out))
279 continue;
280
281 if (flags & UNESCAPE_HEX &&
282 unescape_hex(&src, &out))
283 continue;
284
285 if (flags & UNESCAPE_SPECIAL &&
286 unescape_special(&src, &out))
287 continue;
288
289 *out++ = '\\';
290 }
291 *out++ = *src++;
292 }
293 *out = '\0';
294
295 return out - dst;
296}
297EXPORT_SYMBOL(string_unescape);
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700298
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700299static bool escape_passthrough(unsigned char c, char **dst, char *end)
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700300{
301 char *out = *dst;
302
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700303 if (out < end)
304 *out = c;
305 *dst = out + 1;
306 return true;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700307}
308
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700309static bool escape_space(unsigned char c, char **dst, char *end)
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700310{
311 char *out = *dst;
312 unsigned char to;
313
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700314 switch (c) {
315 case '\n':
316 to = 'n';
317 break;
318 case '\r':
319 to = 'r';
320 break;
321 case '\t':
322 to = 't';
323 break;
324 case '\v':
325 to = 'v';
326 break;
327 case '\f':
328 to = 'f';
329 break;
330 default:
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700331 return false;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700332 }
333
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700334 if (out < end)
335 *out = '\\';
336 ++out;
337 if (out < end)
338 *out = to;
339 ++out;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700340
341 *dst = out;
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700342 return true;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700343}
344
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700345static bool escape_special(unsigned char c, char **dst, char *end)
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700346{
347 char *out = *dst;
348 unsigned char to;
349
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700350 switch (c) {
351 case '\\':
352 to = '\\';
353 break;
354 case '\a':
355 to = 'a';
356 break;
357 case '\e':
358 to = 'e';
359 break;
360 default:
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700361 return false;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700362 }
363
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700364 if (out < end)
365 *out = '\\';
366 ++out;
367 if (out < end)
368 *out = to;
369 ++out;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700370
371 *dst = out;
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700372 return true;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700373}
374
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700375static bool escape_null(unsigned char c, char **dst, char *end)
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700376{
377 char *out = *dst;
378
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700379 if (c)
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700380 return false;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700381
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700382 if (out < end)
383 *out = '\\';
384 ++out;
385 if (out < end)
386 *out = '0';
387 ++out;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700388
389 *dst = out;
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700390 return true;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700391}
392
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700393static bool escape_octal(unsigned char c, char **dst, char *end)
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700394{
395 char *out = *dst;
396
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700397 if (out < end)
398 *out = '\\';
399 ++out;
400 if (out < end)
401 *out = ((c >> 6) & 0x07) + '0';
402 ++out;
403 if (out < end)
404 *out = ((c >> 3) & 0x07) + '0';
405 ++out;
406 if (out < end)
407 *out = ((c >> 0) & 0x07) + '0';
408 ++out;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700409
410 *dst = out;
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700411 return true;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700412}
413
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700414static bool escape_hex(unsigned char c, char **dst, char *end)
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700415{
416 char *out = *dst;
417
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700418 if (out < end)
419 *out = '\\';
420 ++out;
421 if (out < end)
422 *out = 'x';
423 ++out;
424 if (out < end)
425 *out = hex_asc_hi(c);
426 ++out;
427 if (out < end)
428 *out = hex_asc_lo(c);
429 ++out;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700430
431 *dst = out;
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700432 return true;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700433}
434
435/**
436 * string_escape_mem - quote characters in the given memory buffer
437 * @src: source buffer (unescaped)
438 * @isz: source buffer size
439 * @dst: destination buffer (escaped)
440 * @osz: destination buffer size
441 * @flags: combination of the flags (bitwise OR):
Kees Cookd89a3f72015-09-09 15:37:14 -0700442 * %ESCAPE_SPACE: (special white space, not space itself)
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700443 * '\f' - form feed
444 * '\n' - new line
445 * '\r' - carriage return
446 * '\t' - horizontal tab
447 * '\v' - vertical tab
448 * %ESCAPE_SPECIAL:
449 * '\\' - backslash
450 * '\a' - alert (BEL)
451 * '\e' - escape
452 * %ESCAPE_NULL:
453 * '\0' - null
454 * %ESCAPE_OCTAL:
455 * '\NNN' - byte with octal value NNN (3 digits)
456 * %ESCAPE_ANY:
457 * all previous together
458 * %ESCAPE_NP:
459 * escape only non-printable characters (checked by isprint)
460 * %ESCAPE_ANY_NP:
461 * all previous together
462 * %ESCAPE_HEX:
463 * '\xHH' - byte with hexadecimal value HH (2 digits)
Kees Cookb40bdb72015-09-09 15:37:16 -0700464 * @only: NULL-terminated string containing characters used to limit
465 * the selected escape class. If characters are included in @only
Kees Cookd89a3f72015-09-09 15:37:14 -0700466 * that would not normally be escaped by the classes selected
467 * in @flags, they will be copied to @dst unescaped.
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700468 *
469 * Description:
470 * The process of escaping byte buffer includes several parts. They are applied
471 * in the following sequence.
472 * 1. The character is matched to the printable class, if asked, and in
473 * case of match it passes through to the output.
Kees Cookb40bdb72015-09-09 15:37:16 -0700474 * 2. The character is not matched to the one from @only string and thus
Kees Cookd89a3f72015-09-09 15:37:14 -0700475 * must go as-is to the output.
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700476 * 3. The character is checked if it falls into the class given by @flags.
477 * %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any
478 * character. Note that they actually can't go together, otherwise
479 * %ESCAPE_HEX will be ignored.
480 *
481 * Caller must provide valid source and destination pointers. Be aware that
482 * destination buffer will not be NULL-terminated, thus caller have to append
483 * it if needs.
484 *
485 * Return:
Rasmus Villemoes41416f22015-04-15 16:17:28 -0700486 * The total size of the escaped output that would be generated for
487 * the given input and flags. To check whether the output was
488 * truncated, compare the return value to osz. There is room left in
489 * dst for a '\0' terminator if and only if ret < osz.
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700490 */
Rasmus Villemoes41416f22015-04-15 16:17:28 -0700491int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
Kees Cookb40bdb72015-09-09 15:37:16 -0700492 unsigned int flags, const char *only)
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700493{
Rasmus Villemoes41416f22015-04-15 16:17:28 -0700494 char *p = dst;
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700495 char *end = p + osz;
Kees Cookb40bdb72015-09-09 15:37:16 -0700496 bool is_dict = only && *only;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700497
498 while (isz--) {
499 unsigned char c = *src++;
500
501 /*
502 * Apply rules in the following sequence:
503 * - the character is printable, when @flags has
504 * %ESCAPE_NP bit set
Kees Cookb40bdb72015-09-09 15:37:16 -0700505 * - the @only string is supplied and does not contain a
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700506 * character under question
507 * - the character doesn't fall into a class of symbols
508 * defined by given @flags
509 * In these cases we just pass through a character to the
510 * output buffer.
511 */
512 if ((flags & ESCAPE_NP && isprint(c)) ||
Kees Cookb40bdb72015-09-09 15:37:16 -0700513 (is_dict && !strchr(only, c))) {
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700514 /* do nothing */
515 } else {
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700516 if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
517 continue;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700518
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700519 if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
520 continue;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700521
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700522 if (flags & ESCAPE_NULL && escape_null(c, &p, end))
523 continue;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700524
525 /* ESCAPE_OCTAL and ESCAPE_HEX always go last */
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700526 if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700527 continue;
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700528
529 if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700530 continue;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700531 }
532
Rasmus Villemoes3aeddc72015-04-15 16:17:25 -0700533 escape_passthrough(c, &p, end);
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700534 }
535
Rasmus Villemoes41416f22015-04-15 16:17:28 -0700536 return p - dst;
Andy Shevchenkoc8250382014-10-13 15:55:16 -0700537}
538EXPORT_SYMBOL(string_escape_mem);
Kees Cookb53f27e2016-04-20 15:46:23 -0700539
540/*
541 * Return an allocated string that has been escaped of special characters
542 * and double quotes, making it safe to log in quotes.
543 */
544char *kstrdup_quotable(const char *src, gfp_t gfp)
545{
546 size_t slen, dlen;
547 char *dst;
548 const int flags = ESCAPE_HEX;
549 const char esc[] = "\f\n\r\t\v\a\e\\\"";
550
551 if (!src)
552 return NULL;
553 slen = strlen(src);
554
555 dlen = string_escape_mem(src, slen, NULL, 0, flags, esc);
556 dst = kmalloc(dlen + 1, gfp);
557 if (!dst)
558 return NULL;
559
560 WARN_ON(string_escape_mem(src, slen, dst, dlen, flags, esc) != dlen);
561 dst[dlen] = '\0';
562
563 return dst;
564}
565EXPORT_SYMBOL_GPL(kstrdup_quotable);
Kees Cook0d044322016-04-20 15:46:24 -0700566
567/*
568 * Returns allocated NULL-terminated string containing process
569 * command line, with inter-argument NULLs replaced with spaces,
570 * and other special characters escaped.
571 */
572char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp)
573{
574 char *buffer, *quoted;
575 int i, res;
576
577 buffer = kmalloc(PAGE_SIZE, GFP_TEMPORARY);
578 if (!buffer)
579 return NULL;
580
581 res = get_cmdline(task, buffer, PAGE_SIZE - 1);
582 buffer[res] = '\0';
583
584 /* Collapse trailing NULLs, leave res pointing to last non-NULL. */
585 while (--res >= 0 && buffer[res] == '\0')
586 ;
587
588 /* Replace inter-argument NULLs. */
589 for (i = 0; i <= res; i++)
590 if (buffer[i] == '\0')
591 buffer[i] = ' ';
592
593 /* Make sure result is printable. */
594 quoted = kstrdup_quotable(buffer, gfp);
595 kfree(buffer);
596 return quoted;
597}
598EXPORT_SYMBOL_GPL(kstrdup_quotable_cmdline);