LCOV - code coverage report
Current view: top level - lib - string_helpers.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 50 285 17.5 %
Date: 2021-04-22 12:43:58 Functions: 2 16 12.5 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * Helpers for formatting and printing strings
       4             :  *
       5             :  * Copyright 31 August 2008 James Bottomley
       6             :  * Copyright (C) 2013, Intel Corporation
       7             :  */
       8             : #include <linux/bug.h>
       9             : #include <linux/kernel.h>
      10             : #include <linux/math64.h>
      11             : #include <linux/export.h>
      12             : #include <linux/ctype.h>
      13             : #include <linux/errno.h>
      14             : #include <linux/fs.h>
      15             : #include <linux/limits.h>
      16             : #include <linux/mm.h>
      17             : #include <linux/slab.h>
      18             : #include <linux/string.h>
      19             : #include <linux/string_helpers.h>
      20             : 
      21             : /**
      22             :  * string_get_size - get the size in the specified units
      23             :  * @size:       The size to be converted in blocks
      24             :  * @blk_size:   Size of the block (use 1 for size in bytes)
      25             :  * @units:      units to use (powers of 1000 or 1024)
      26             :  * @buf:        buffer to format to
      27             :  * @len:        length of buffer
      28             :  *
      29             :  * This function returns a string formatted to 3 significant figures
      30             :  * giving the size in the required units.  @buf should have room for
      31             :  * at least 9 bytes and will always be zero terminated.
      32             :  *
      33             :  */
      34           2 : void string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
      35             :                      char *buf, int len)
      36             : {
      37           2 :         static const char *const units_10[] = {
      38             :                 "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
      39             :         };
      40           2 :         static const char *const units_2[] = {
      41             :                 "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
      42             :         };
      43           2 :         static const char *const *const units_str[] = {
      44             :                 [STRING_UNITS_10] = units_10,
      45             :                 [STRING_UNITS_2] = units_2,
      46             :         };
      47           2 :         static const unsigned int divisor[] = {
      48             :                 [STRING_UNITS_10] = 1000,
      49             :                 [STRING_UNITS_2] = 1024,
      50             :         };
      51           2 :         static const unsigned int rounding[] = { 500, 50, 5 };
      52           2 :         int i = 0, j;
      53           2 :         u32 remainder = 0, sf_cap;
      54           2 :         char tmp[8];
      55           2 :         const char *unit;
      56             : 
      57           2 :         tmp[0] = '\0';
      58             : 
      59           2 :         if (blk_size == 0)
      60             :                 size = 0;
      61           2 :         if (size == 0)
      62           0 :                 goto out;
      63             : 
      64             :         /* This is Napier's algorithm.  Reduce the original block size to
      65             :          *
      66             :          * coefficient * divisor[units]^i
      67             :          *
      68             :          * we do the reduction so both coefficients are just under 32 bits so
      69             :          * that multiplying them together won't overflow 64 bits and we keep
      70             :          * as much precision as possible in the numbers.
      71             :          *
      72             :          * Note: it's safe to throw away the remainders here because all the
      73             :          * precision is in the coefficients.
      74             :          */
      75           2 :         while (blk_size >> 32) {
      76           0 :                 do_div(blk_size, divisor[units]);
      77           0 :                 i++;
      78             :         }
      79             : 
      80           2 :         while (size >> 32) {
      81           0 :                 do_div(size, divisor[units]);
      82           0 :                 i++;
      83             :         }
      84             : 
      85             :         /* now perform the actual multiplication keeping i as the sum of the
      86             :          * two logarithms */
      87           2 :         size *= blk_size;
      88             : 
      89             :         /* and logarithmically reduce it until it's just under the divisor */
      90           8 :         while (size >= divisor[units]) {
      91           6 :                 remainder = do_div(size, divisor[units]);
      92           6 :                 i++;
      93             :         }
      94             : 
      95             :         /* work out in j how many digits of precision we need from the
      96             :          * remainder */
      97           2 :         sf_cap = size;
      98           6 :         for (j = 0; sf_cap*10 < 1000; j++)
      99           4 :                 sf_cap *= 10;
     100             : 
     101           2 :         if (units == STRING_UNITS_2) {
     102             :                 /* express the remainder as a decimal.  It's currently the
     103             :                  * numerator of a fraction whose denominator is
     104             :                  * divisor[units], which is 1 << 10 for STRING_UNITS_2 */
     105           1 :                 remainder *= 1000;
     106           1 :                 remainder >>= 10;
     107             :         }
     108             : 
     109             :         /* add a 5 to the digit below what will be printed to ensure
     110             :          * an arithmetical round up and carry it through to size */
     111           2 :         remainder += rounding[j];
     112           2 :         if (remainder >= 1000) {
     113           0 :                 remainder -= 1000;
     114           0 :                 size += 1;
     115             :         }
     116             : 
     117           2 :         if (j) {
     118           2 :                 snprintf(tmp, sizeof(tmp), ".%03u", remainder);
     119           2 :                 tmp[j+1] = '\0';
     120             :         }
     121             : 
     122           0 :  out:
     123           2 :         if (i >= ARRAY_SIZE(units_2))
     124             :                 unit = "UNK";
     125             :         else
     126           2 :                 unit = units_str[units][i];
     127             : 
     128           2 :         snprintf(buf, len, "%u%s %s", (u32)size,
     129             :                  tmp, unit);
     130           2 : }
     131             : EXPORT_SYMBOL(string_get_size);
     132             : 
     133           0 : static bool unescape_space(char **src, char **dst)
     134             : {
     135           0 :         char *p = *dst, *q = *src;
     136             : 
     137           0 :         switch (*q) {
     138           0 :         case 'n':
     139           0 :                 *p = '\n';
     140           0 :                 break;
     141           0 :         case 'r':
     142           0 :                 *p = '\r';
     143           0 :                 break;
     144           0 :         case 't':
     145           0 :                 *p = '\t';
     146           0 :                 break;
     147           0 :         case 'v':
     148           0 :                 *p = '\v';
     149           0 :                 break;
     150           0 :         case 'f':
     151           0 :                 *p = '\f';
     152           0 :                 break;
     153             :         default:
     154             :                 return false;
     155             :         }
     156           0 :         *dst += 1;
     157           0 :         *src += 1;
     158           0 :         return true;
     159             : }
     160             : 
     161           0 : static bool unescape_octal(char **src, char **dst)
     162             : {
     163           0 :         char *p = *dst, *q = *src;
     164           0 :         u8 num;
     165             : 
     166           0 :         if (isodigit(*q) == 0)
     167             :                 return false;
     168             : 
     169           0 :         num = (*q++) & 7;
     170           0 :         while (num < 32 && isodigit(*q) && (q - *src < 3)) {
     171           0 :                 num <<= 3;
     172           0 :                 num += (*q++) & 7;
     173             :         }
     174           0 :         *p = num;
     175           0 :         *dst += 1;
     176           0 :         *src = q;
     177           0 :         return true;
     178             : }
     179             : 
     180           0 : static bool unescape_hex(char **src, char **dst)
     181             : {
     182           0 :         char *p = *dst, *q = *src;
     183           0 :         int digit;
     184           0 :         u8 num;
     185             : 
     186           0 :         if (*q++ != 'x')
     187             :                 return false;
     188             : 
     189           0 :         num = digit = hex_to_bin(*q++);
     190           0 :         if (digit < 0)
     191             :                 return false;
     192             : 
     193           0 :         digit = hex_to_bin(*q);
     194           0 :         if (digit >= 0) {
     195           0 :                 q++;
     196           0 :                 num = (num << 4) | digit;
     197             :         }
     198           0 :         *p = num;
     199           0 :         *dst += 1;
     200           0 :         *src = q;
     201           0 :         return true;
     202             : }
     203             : 
     204           0 : static bool unescape_special(char **src, char **dst)
     205             : {
     206           0 :         char *p = *dst, *q = *src;
     207             : 
     208           0 :         switch (*q) {
     209           0 :         case '\"':
     210           0 :                 *p = '\"';
     211           0 :                 break;
     212           0 :         case '\\':
     213           0 :                 *p = '\\';
     214           0 :                 break;
     215           0 :         case 'a':
     216           0 :                 *p = '\a';
     217           0 :                 break;
     218           0 :         case 'e':
     219           0 :                 *p = '\e';
     220           0 :                 break;
     221             :         default:
     222             :                 return false;
     223             :         }
     224           0 :         *dst += 1;
     225           0 :         *src += 1;
     226           0 :         return true;
     227             : }
     228             : 
     229             : /**
     230             :  * string_unescape - unquote characters in the given string
     231             :  * @src:        source buffer (escaped)
     232             :  * @dst:        destination buffer (unescaped)
     233             :  * @size:       size of the destination buffer (0 to unlimit)
     234             :  * @flags:      combination of the flags.
     235             :  *
     236             :  * Description:
     237             :  * The function unquotes characters in the given string.
     238             :  *
     239             :  * Because the size of the output will be the same as or less than the size of
     240             :  * the input, the transformation may be performed in place.
     241             :  *
     242             :  * Caller must provide valid source and destination pointers. Be aware that
     243             :  * destination buffer will always be NULL-terminated. Source string must be
     244             :  * NULL-terminated as well.  The supported flags are::
     245             :  *
     246             :  *      UNESCAPE_SPACE:
     247             :  *              '\f' - form feed
     248             :  *              '\n' - new line
     249             :  *              '\r' - carriage return
     250             :  *              '\t' - horizontal tab
     251             :  *              '\v' - vertical tab
     252             :  *      UNESCAPE_OCTAL:
     253             :  *              '\NNN' - byte with octal value NNN (1 to 3 digits)
     254             :  *      UNESCAPE_HEX:
     255             :  *              '\xHH' - byte with hexadecimal value HH (1 to 2 digits)
     256             :  *      UNESCAPE_SPECIAL:
     257             :  *              '\"' - double quote
     258             :  *              '\\' - backslash
     259             :  *              '\a' - alert (BEL)
     260             :  *              '\e' - escape
     261             :  *      UNESCAPE_ANY:
     262             :  *              all previous together
     263             :  *
     264             :  * Return:
     265             :  * The amount of the characters processed to the destination buffer excluding
     266             :  * trailing '\0' is returned.
     267             :  */
     268           0 : int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
     269             : {
     270           0 :         char *out = dst;
     271             : 
     272           0 :         while (*src && --size) {
     273           0 :                 if (src[0] == '\\' && src[1] != '\0' && size > 1) {
     274           0 :                         src++;
     275           0 :                         size--;
     276             : 
     277           0 :                         if (flags & UNESCAPE_SPACE &&
     278           0 :                                         unescape_space(&src, &out))
     279           0 :                                 continue;
     280             : 
     281           0 :                         if (flags & UNESCAPE_OCTAL &&
     282           0 :                                         unescape_octal(&src, &out))
     283           0 :                                 continue;
     284             : 
     285           0 :                         if (flags & UNESCAPE_HEX &&
     286           0 :                                         unescape_hex(&src, &out))
     287           0 :                                 continue;
     288             : 
     289           0 :                         if (flags & UNESCAPE_SPECIAL &&
     290           0 :                                         unescape_special(&src, &out))
     291           0 :                                 continue;
     292             : 
     293           0 :                         *out++ = '\\';
     294             :                 }
     295           0 :                 *out++ = *src++;
     296             :         }
     297           0 :         *out = '\0';
     298             : 
     299           0 :         return out - dst;
     300             : }
     301             : EXPORT_SYMBOL(string_unescape);
     302             : 
     303       58455 : static bool escape_passthrough(unsigned char c, char **dst, char *end)
     304             : {
     305       58455 :         char *out = *dst;
     306             : 
     307       58455 :         if (out < end)
     308       58454 :                 *out = c;
     309       58455 :         *dst = out + 1;
     310       58455 :         return true;
     311             : }
     312             : 
     313           0 : static bool escape_space(unsigned char c, char **dst, char *end)
     314             : {
     315           0 :         char *out = *dst;
     316           0 :         unsigned char to;
     317             : 
     318           0 :         switch (c) {
     319             :         case '\n':
     320             :                 to = 'n';
     321             :                 break;
     322             :         case '\r':
     323             :                 to = 'r';
     324             :                 break;
     325             :         case '\t':
     326             :                 to = 't';
     327             :                 break;
     328             :         case '\v':
     329             :                 to = 'v';
     330             :                 break;
     331             :         case '\f':
     332             :                 to = 'f';
     333             :                 break;
     334             :         default:
     335             :                 return false;
     336             :         }
     337             : 
     338           0 :         if (out < end)
     339           0 :                 *out = '\\';
     340           0 :         ++out;
     341           0 :         if (out < end)
     342           0 :                 *out = to;
     343           0 :         ++out;
     344             : 
     345           0 :         *dst = out;
     346           0 :         return true;
     347             : }
     348             : 
     349           0 : static bool escape_special(unsigned char c, char **dst, char *end)
     350             : {
     351           0 :         char *out = *dst;
     352           0 :         unsigned char to;
     353             : 
     354           0 :         switch (c) {
     355             :         case '\\':
     356             :                 to = '\\';
     357             :                 break;
     358           0 :         case '\a':
     359           0 :                 to = 'a';
     360           0 :                 break;
     361           0 :         case '\e':
     362           0 :                 to = 'e';
     363           0 :                 break;
     364             :         default:
     365             :                 return false;
     366             :         }
     367             : 
     368           0 :         if (out < end)
     369           0 :                 *out = '\\';
     370           0 :         ++out;
     371           0 :         if (out < end)
     372           0 :                 *out = to;
     373           0 :         ++out;
     374             : 
     375           0 :         *dst = out;
     376           0 :         return true;
     377             : }
     378             : 
     379           0 : static bool escape_null(unsigned char c, char **dst, char *end)
     380             : {
     381           0 :         char *out = *dst;
     382             : 
     383           0 :         if (c)
     384             :                 return false;
     385             : 
     386           0 :         if (out < end)
     387           0 :                 *out = '\\';
     388           0 :         ++out;
     389           0 :         if (out < end)
     390           0 :                 *out = '0';
     391           0 :         ++out;
     392             : 
     393           0 :         *dst = out;
     394           0 :         return true;
     395             : }
     396             : 
     397           0 : static bool escape_octal(unsigned char c, char **dst, char *end)
     398             : {
     399           0 :         char *out = *dst;
     400             : 
     401           0 :         if (out < end)
     402           0 :                 *out = '\\';
     403           0 :         ++out;
     404           0 :         if (out < end)
     405           0 :                 *out = ((c >> 6) & 0x07) + '0';
     406           0 :         ++out;
     407           0 :         if (out < end)
     408           0 :                 *out = ((c >> 3) & 0x07) + '0';
     409           0 :         ++out;
     410           0 :         if (out < end)
     411           0 :                 *out = ((c >> 0) & 0x07) + '0';
     412           0 :         ++out;
     413             : 
     414           0 :         *dst = out;
     415           0 :         return true;
     416             : }
     417             : 
     418           0 : static bool escape_hex(unsigned char c, char **dst, char *end)
     419             : {
     420           0 :         char *out = *dst;
     421             : 
     422           0 :         if (out < end)
     423           0 :                 *out = '\\';
     424           0 :         ++out;
     425           0 :         if (out < end)
     426           0 :                 *out = 'x';
     427           0 :         ++out;
     428           0 :         if (out < end)
     429           0 :                 *out = hex_asc_hi(c);
     430           0 :         ++out;
     431           0 :         if (out < end)
     432           0 :                 *out = hex_asc_lo(c);
     433           0 :         ++out;
     434             : 
     435           0 :         *dst = out;
     436           0 :         return true;
     437             : }
     438             : 
     439             : /**
     440             :  * string_escape_mem - quote characters in the given memory buffer
     441             :  * @src:        source buffer (unescaped)
     442             :  * @isz:        source buffer size
     443             :  * @dst:        destination buffer (escaped)
     444             :  * @osz:        destination buffer size
     445             :  * @flags:      combination of the flags
     446             :  * @only:       NULL-terminated string containing characters used to limit
     447             :  *              the selected escape class. If characters are included in @only
     448             :  *              that would not normally be escaped by the classes selected
     449             :  *              in @flags, they will be copied to @dst unescaped.
     450             :  *
     451             :  * Description:
     452             :  * The process of escaping byte buffer includes several parts. They are applied
     453             :  * in the following sequence.
     454             :  *
     455             :  *      1. The character is matched to the printable class, if asked, and in
     456             :  *         case of match it passes through to the output.
     457             :  *      2. The character is not matched to the one from @only string and thus
     458             :  *         must go as-is to the output.
     459             :  *      3. The character is checked if it falls into the class given by @flags.
     460             :  *         %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any
     461             :  *         character. Note that they actually can't go together, otherwise
     462             :  *         %ESCAPE_HEX will be ignored.
     463             :  *
     464             :  * Caller must provide valid source and destination pointers. Be aware that
     465             :  * destination buffer will not be NULL-terminated, thus caller have to append
     466             :  * it if needs.   The supported flags are::
     467             :  *
     468             :  *      %ESCAPE_SPACE: (special white space, not space itself)
     469             :  *              '\f' - form feed
     470             :  *              '\n' - new line
     471             :  *              '\r' - carriage return
     472             :  *              '\t' - horizontal tab
     473             :  *              '\v' - vertical tab
     474             :  *      %ESCAPE_SPECIAL:
     475             :  *              '\\' - backslash
     476             :  *              '\a' - alert (BEL)
     477             :  *              '\e' - escape
     478             :  *      %ESCAPE_NULL:
     479             :  *              '\0' - null
     480             :  *      %ESCAPE_OCTAL:
     481             :  *              '\NNN' - byte with octal value NNN (3 digits)
     482             :  *      %ESCAPE_ANY:
     483             :  *              all previous together
     484             :  *      %ESCAPE_NP:
     485             :  *              escape only non-printable characters (checked by isprint)
     486             :  *      %ESCAPE_ANY_NP:
     487             :  *              all previous together
     488             :  *      %ESCAPE_HEX:
     489             :  *              '\xHH' - byte with hexadecimal value HH (2 digits)
     490             :  *
     491             :  * Return:
     492             :  * The total size of the escaped output that would be generated for
     493             :  * the given input and flags. To check whether the output was
     494             :  * truncated, compare the return value to osz. There is room left in
     495             :  * dst for a '\0' terminator if and only if ret < osz.
     496             :  */
     497       10889 : int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
     498             :                       unsigned int flags, const char *only)
     499             : {
     500       10889 :         char *p = dst;
     501       10889 :         char *end = p + osz;
     502       10889 :         bool is_dict = only && *only;
     503             : 
     504       10889 :         while (isz--) {
     505       58453 :                 unsigned char c = *src++;
     506             : 
     507             :                 /*
     508             :                  * Apply rules in the following sequence:
     509             :                  *      - the character is printable, when @flags has
     510             :                  *        %ESCAPE_NP bit set
     511             :                  *      - the @only string is supplied and does not contain a
     512             :                  *        character under question
     513             :                  *      - the character doesn't fall into a class of symbols
     514             :                  *        defined by given @flags
     515             :                  * In these cases we just pass through a character to the
     516             :                  * output buffer.
     517             :                  */
     518       58453 :                 if ((flags & ESCAPE_NP && isprint(c)) ||
     519       58447 :                     (is_dict && !strchr(only, c))) {
     520             :                         /* do nothing */
     521             :                 } else {
     522           0 :                         if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
     523           0 :                                 continue;
     524             : 
     525           0 :                         if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
     526           0 :                                 continue;
     527             : 
     528           0 :                         if (flags & ESCAPE_NULL && escape_null(c, &p, end))
     529           0 :                                 continue;
     530             : 
     531             :                         /* ESCAPE_OCTAL and ESCAPE_HEX always go last */
     532           0 :                         if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
     533           0 :                                 continue;
     534             : 
     535           0 :                         if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
     536           0 :                                 continue;
     537             :                 }
     538             : 
     539      127799 :                 escape_passthrough(c, &p, end);
     540             :         }
     541             : 
     542       10891 :         return p - dst;
     543             : }
     544             : EXPORT_SYMBOL(string_escape_mem);
     545             : 
     546           0 : int string_escape_mem_ascii(const char *src, size_t isz, char *dst,
     547             :                                         size_t osz)
     548             : {
     549           0 :         char *p = dst;
     550           0 :         char *end = p + osz;
     551             : 
     552           0 :         while (isz--) {
     553           0 :                 unsigned char c = *src++;
     554             : 
     555           0 :                 if (!isprint(c) || !isascii(c) || c == '"' || c == '\\')
     556           0 :                         escape_hex(c, &p, end);
     557             :                 else
     558           0 :                         escape_passthrough(c, &p, end);
     559             :         }
     560             : 
     561           0 :         return p - dst;
     562             : }
     563             : EXPORT_SYMBOL(string_escape_mem_ascii);
     564             : 
     565             : /*
     566             :  * Return an allocated string that has been escaped of special characters
     567             :  * and double quotes, making it safe to log in quotes.
     568             :  */
     569           0 : char *kstrdup_quotable(const char *src, gfp_t gfp)
     570             : {
     571           0 :         size_t slen, dlen;
     572           0 :         char *dst;
     573           0 :         const int flags = ESCAPE_HEX;
     574           0 :         const char esc[] = "\f\n\r\t\v\a\e\\\"";
     575             : 
     576           0 :         if (!src)
     577             :                 return NULL;
     578           0 :         slen = strlen(src);
     579             : 
     580           0 :         dlen = string_escape_mem(src, slen, NULL, 0, flags, esc);
     581           0 :         dst = kmalloc(dlen + 1, gfp);
     582           0 :         if (!dst)
     583             :                 return NULL;
     584             : 
     585           0 :         WARN_ON(string_escape_mem(src, slen, dst, dlen, flags, esc) != dlen);
     586           0 :         dst[dlen] = '\0';
     587             : 
     588           0 :         return dst;
     589             : }
     590             : EXPORT_SYMBOL_GPL(kstrdup_quotable);
     591             : 
     592             : /*
     593             :  * Returns allocated NULL-terminated string containing process
     594             :  * command line, with inter-argument NULLs replaced with spaces,
     595             :  * and other special characters escaped.
     596             :  */
     597           0 : char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp)
     598             : {
     599           0 :         char *buffer, *quoted;
     600           0 :         int i, res;
     601             : 
     602           0 :         buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
     603           0 :         if (!buffer)
     604             :                 return NULL;
     605             : 
     606           0 :         res = get_cmdline(task, buffer, PAGE_SIZE - 1);
     607           0 :         buffer[res] = '\0';
     608             : 
     609             :         /* Collapse trailing NULLs, leave res pointing to last non-NULL. */
     610           0 :         while (--res >= 0 && buffer[res] == '\0')
     611           0 :                 ;
     612             : 
     613             :         /* Replace inter-argument NULLs. */
     614           0 :         for (i = 0; i <= res; i++)
     615           0 :                 if (buffer[i] == '\0')
     616           0 :                         buffer[i] = ' ';
     617             : 
     618             :         /* Make sure result is printable. */
     619           0 :         quoted = kstrdup_quotable(buffer, gfp);
     620           0 :         kfree(buffer);
     621           0 :         return quoted;
     622             : }
     623             : EXPORT_SYMBOL_GPL(kstrdup_quotable_cmdline);
     624             : 
     625             : /*
     626             :  * Returns allocated NULL-terminated string containing pathname,
     627             :  * with special characters escaped, able to be safely logged. If
     628             :  * there is an error, the leading character will be "<".
     629             :  */
     630           0 : char *kstrdup_quotable_file(struct file *file, gfp_t gfp)
     631             : {
     632           0 :         char *temp, *pathname;
     633             : 
     634           0 :         if (!file)
     635           0 :                 return kstrdup("<unknown>", gfp);
     636             : 
     637             :         /* We add 11 spaces for ' (deleted)' to be appended */
     638           0 :         temp = kmalloc(PATH_MAX + 11, GFP_KERNEL);
     639           0 :         if (!temp)
     640           0 :                 return kstrdup("<no_memory>", gfp);
     641             : 
     642           0 :         pathname = file_path(file, temp, PATH_MAX + 11);
     643           0 :         if (IS_ERR(pathname))
     644           0 :                 pathname = kstrdup("<too_long>", gfp);
     645             :         else
     646           0 :                 pathname = kstrdup_quotable(pathname, gfp);
     647             : 
     648           0 :         kfree(temp);
     649           0 :         return pathname;
     650             : }
     651             : EXPORT_SYMBOL_GPL(kstrdup_quotable_file);
     652             : 
     653             : /**
     654             :  * kfree_strarray - free a number of dynamically allocated strings contained
     655             :  *                  in an array and the array itself
     656             :  *
     657             :  * @array: Dynamically allocated array of strings to free.
     658             :  * @n: Number of strings (starting from the beginning of the array) to free.
     659             :  *
     660             :  * Passing a non-NULL @array and @n == 0 as well as NULL @array are valid
     661             :  * use-cases. If @array is NULL, the function does nothing.
     662             :  */
     663           0 : void kfree_strarray(char **array, size_t n)
     664             : {
     665           0 :         unsigned int i;
     666             : 
     667           0 :         if (!array)
     668             :                 return;
     669             : 
     670           0 :         for (i = 0; i < n; i++)
     671           0 :                 kfree(array[i]);
     672           0 :         kfree(array);
     673             : }
     674             : EXPORT_SYMBOL_GPL(kfree_strarray);

Generated by: LCOV version 1.14