brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.9 KiB · cb7ea41 Raw
236 lines · plain
1.. title:: clang-tidy - bugprone-unsafe-functions2 3bugprone-unsafe-functions4=========================5 6Checks for functions that have safer, more secure replacements available, or7are considered deprecated due to design flaws.8The check heavily relies on the functions from the9**Annex K.** "Bounds-checking interfaces" of C11.10 11The check implements the following rules from the CERT C Coding Standard:12  - Recommendation `MSC24-C. Do not use deprecated or obsolescent functions13    <https://wiki.sei.cmu.edu/confluence/display/c/MSC24-C.+Do+not+use+deprecated+or+obsolescent+functions>`_.14  - Rule `MSC33-C. Do not pass invalid data to the asctime() function15    <https://wiki.sei.cmu.edu/confluence/display/c/MSC33-C.+Do+not+pass+invalid+data+to+the+asctime%28%29+function>`_.16 17`cert-msc24-c` and `cert-msc33-c` redirect here as aliases of this check.18 19Unsafe functions20----------------21 22The following functions are reported if :option:`ReportDefaultFunctions`23is enabled.24 25If *Annex K.* is available, a replacement from *Annex K.* is suggested for the26following functions:27 28``asctime``, ``asctime_r``, ``bsearch``, ``ctime``, ``fopen``, ``fprintf``,29``freopen``, ``fscanf``, ``fwprintf``, ``fwscanf``, ``getenv``, ``gets``,30``gmtime``, ``localtime``, ``mbsrtowcs``, ``mbstowcs``, ``memcpy``,31``memmove``, ``memset``, ``printf``, ``qsort``, ``scanf``,  ``snprintf``,32``sprintf``,  ``sscanf``, ``strcat``, ``strcpy``, ``strerror``, ``strlen``,33``strncat``, ``strncpy``, ``strtok``, ``swprintf``, ``swscanf``, ``vfprintf``,34``vfscanf``, ``vfwprintf``, ``vfwscanf``, ``vprintf``, ``vscanf``,35``vsnprintf``, ``vsprintf``, ``vsscanf``, ``vswprintf``, ``vswscanf``,36``vwprintf``, ``vwscanf``, ``wcrtomb``, ``wcscat``, ``wcscpy``,37``wcslen``, ``wcsncat``, ``wcsncpy``, ``wcsrtombs``, ``wcstok``, ``wcstombs``,38``wctomb``, ``wmemcpy``, ``wmemmove``, ``wprintf``, ``wscanf``.39 40If *Annex K.* is not available, replacements are suggested only for the41following functions from the previous list:42 43 - ``asctime``, ``asctime_r``, suggested replacement: ``strftime``44 - ``gets``, suggested replacement: ``fgets``45 46The following functions are always checked, regardless of *Annex K*47availability:48 49 - ``rewind``, suggested replacement: ``fseek``50 - ``setbuf``, suggested replacement: ``setvbuf``51 52If :option:`ReportMoreUnsafeFunctions` is enabled,53the following functions are also checked:54 55 - ``bcmp``, suggested replacement: ``memcmp``56 - ``bcopy``, suggested replacement: ``memcpy_s`` if *Annex K* is available,57   or ``memcpy``58 - ``bzero``, suggested replacement: ``memset_s`` if *Annex K* is available,59   or ``memset``60 - ``getpw``, suggested replacement: ``getpwuid``61 - ``vfork``, suggested replacement: ``posix_spawn``62 63Although mentioned in the associated CERT rules, the following functions are64**ignored** by the check:65 66``atof``, ``atoi``, ``atol``, ``atoll``, ``tmpfile``.67 68The availability of *Annex K* is determined based on the following macros:69 70 - ``__STDC_LIB_EXT1__``: feature macro, which indicates the presence of71   *Annex K. "Bounds-checking interfaces"* in the library implementation72 - ``__STDC_WANT_LIB_EXT1__``: user-defined macro, which indicates that the73   user requests the functions from *Annex K.* to be defined.74 75Both macros have to be defined to suggest replacement functions from *Annex K.*76``__STDC_LIB_EXT1__`` is defined by the library implementation, and77``__STDC_WANT_LIB_EXT1__`` must be defined to ``1`` by the user **before**78including any system headers.79 80.. _CustomFunctions:81 82Custom functions83----------------84 85The option :option:`CustomFunctions` allows the user to define custom functions86to be checked. The format is the following, without newlines:87 88.. code::89 90   bugprone-unsafe-functions.CustomFunctions="91     functionRegex1[, replacement1[, reason1]];92     functionRegex2[, replacement2[, reason2]];93     ...94   "95 96The functions are matched using POSIX extended regular expressions.97*(Note: The regular expressions do not support negative* ``(?!)`` *matches.)*98 99The ``reason`` is optional and is used to provide additional information about the100reasoning behind the replacement. The default reason is ``is marked as unsafe``.101 102If ``replacement`` is empty, the default text ``it should not be used`` will be103shown instead of the suggestion for a replacement.104 105If the ``reason`` starts with the character ``>``, the reason becomes fully custom.106The default suffix is disabled even if a ``replacement`` is present, and only the107reason message is shown after the matched function, to allow better control over108the suggestions. (The starting ``>`` and whitespace directly after it are109trimmed from the message.)110 111As an example, the following configuration matches only the function ``original``112in the default namespace. A similar diagnostic can also be printed using a fully113custom reason.114 115.. code:: c116 117   // bugprone-unsafe-functions.CustomFunctions:118   //   ^original$, replacement, is deprecated;119   // Using the fully custom message syntax:120   //   ^suspicious$,,> should be avoided if possible.121   original(); // warning: function 'original' is deprecated; 'replacement' should be used instead.122   suspicious(); // warning: function 'suspicious' should be avoided if possible.123   ::std::original(); // no-warning124   original_function(); // no-warning125 126If the regular expression contains the character ``:``, it is matched against the127qualified name (i.e. ``std::original``), otherwise the regex is matched against128the unqualified name (``original``). If the regular expression starts with ``::``129(or ``^::``), it is matched against the fully qualified name130(``::std::original``).131 132One of the use cases for fully custom messages is suggesting compiler options133and warning flags:134 135.. code:: c136 137   // bugprone-unsafe-functions.CustomFunctions:138   //   ^memcpy$,,>is recommended to have compiler hardening using '_FORTIFY_SOURCE';139   //   ^printf$,,>is recommended to have the '-Werror=format-security' compiler warning flag;140 141   memcpy(dest, src, 999'999); // warning: function 'memcpy' is recommended to have compiler hardening using '_FORTIFY_SOURCE'142   printf(raw_str); // warning: function 'printf' is recommended to have the '-Werror=format-security' compiler warning flag143 144.. note::145 146   Fully qualified names can contain template parameters on certain C++ classes,147   but not on C++ functions. Type aliases are resolved before matching.148 149   As an example, the member function ``open`` in the class ``std::ifstream``150   has a fully qualified name of ``::std::basic_ifstream<char>::open``.151 152   The example could also be matched with the regex153   ``::std::basic_ifstream<[^>]*>::open``, which matches all potential template154   parameters, but does not match nested template classes.155 156Options157-------158 159.. option:: ReportMoreUnsafeFunctions160 161   When `true`, additional functions from widely used APIs (such as POSIX) are162   added to the list of reported functions.163   See the main documentation of the check for the complete list as to what164   this option enables.165   Default is `true`.166 167.. option:: ReportDefaultFunctions168 169    When `true`, the check reports the default set of functions.170    Consider changing the setting to false if you only want to see custom171    functions matched via :ref:`custom functions<CustomFunctions>`.172    Default is `true`.173 174.. option:: CustomFunctions175 176    A semicolon-separated list of custom functions to be matched. A matched177    function contains a regular expression, an optional name of the replacement178    function, and an optional reason, separated by comma. For more information,179    see :ref:`Custom functions<CustomFunctions>`.180 181Examples182--------183 184.. code-block:: c++185 186    #ifndef __STDC_LIB_EXT1__187    #error "Annex K is not supported by the current standard library implementation."188    #endif189 190    #define __STDC_WANT_LIB_EXT1__ 1191 192    #include <string.h> // Defines functions from Annex K.193    #include <stdio.h>194 195    enum { BUFSIZE = 32 };196 197    void Unsafe(const char *Msg) {198      static const char Prefix[] = "Error: ";199      static const char Suffix[] = "\n";200      char Buf[BUFSIZE] = {0};201 202      strcpy(Buf, Prefix); // warning: function 'strcpy' is not bounds-checking; 'strcpy_s' should be used instead.203      strcat(Buf, Msg);    // warning: function 'strcat' is not bounds-checking; 'strcat_s' should be used instead.204      strcat(Buf, Suffix); // warning: function 'strcat' is not bounds-checking; 'strcat_s' should be used instead.205      if (fputs(buf, stderr) < 0) {206        // error handling207        return;208      }209    }210 211    void UsingSafeFunctions(const char *Msg) {212      static const char Prefix[] = "Error: ";213      static const char Suffix[] = "\n";214      char Buf[BUFSIZE] = {0};215 216      if (strcpy_s(Buf, BUFSIZE, Prefix) != 0) {217        // error handling218        return;219      }220 221      if (strcat_s(Buf, BUFSIZE, Msg) != 0) {222        // error handling223        return;224      }225 226      if (strcat_s(Buf, BUFSIZE, Suffix) != 0) {227        // error handling228        return;229      }230 231      if (fputs(Buf, stderr) < 0) {232        // error handling233        return;234      }235    }236