1 .. title:: clang-tidy - bugprone-unsafe-functions
3 bugprone-unsafe-functions
4 =========================
6 Checks for functions that have safer, more secure replacements available, or
7 are considered deprecated due to design flaws.
8 The check heavily relies on the functions from the
9 **Annex K.** "Bounds-checking interfaces" of C11.
11 The check implements the following rules from the CERT C Coding Standard:
12 - Recommendation `MSC24-C. Do not use deprecated or obsolescent functions
13 <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() function
15 <https://wiki.sei.cmu.edu/confluence/display/c/MSC33-C.+Do+not+pass+invalid+data+to+the+asctime%28%29+function>`_.
17 `cert-msc24-c` and `cert-msc33-c` redirect here as aliases of this check.
22 If *Annex K.* is available, a replacement from *Annex K.* is suggested for the
25 ``asctime``, ``asctime_r``, ``bsearch``, ``ctime``, ``fopen``, ``fprintf``,
26 ``freopen``, ``fscanf``, ``fwprintf``, ``fwscanf``, ``getenv``, ``gets``,
27 ``gmtime``, ``localtime``, ``mbsrtowcs``, ``mbstowcs``, ``memcpy``,
28 ``memmove``, ``memset``, ``printf``, ``qsort``, ``scanf``, ``snprintf``,
29 ``sprintf``, ``sscanf``, ``strcat``, ``strcpy``, ``strerror``, ``strlen``,
30 ``strncat``, ``strncpy``, ``strtok``, ``swprintf``, ``swscanf``, ``vfprintf``,
31 ``vfscanf``, ``vfwprintf``, ``vfwscanf``, ``vprintf``, ``vscanf``,
32 ``vsnprintf``, ``vsprintf``, ``vsscanf``, ``vswprintf``, ``vswscanf``,
33 ``vwprintf``, ``vwscanf``, ``wcrtomb``, ``wcscat``, ``wcscpy``,
34 ``wcslen``, ``wcsncat``, ``wcsncpy``, ``wcsrtombs``, ``wcstok``, ``wcstombs``,
35 ``wctomb``, ``wmemcpy``, ``wmemmove``, ``wprintf``, ``wscanf``.
37 If *Annex K.* is not available, replacements are suggested only for the
38 following functions from the previous list:
40 - ``asctime``, ``asctime_r``, suggested replacement: ``strftime``
41 - ``gets``, suggested replacement: ``fgets``
43 The following functions are always checked, regardless of *Annex K* availability:
45 - ``rewind``, suggested replacement: ``fseek``
46 - ``setbuf``, suggested replacement: ``setvbuf``
48 If `ReportMoreUnsafeFunctions
49 <unsafe-functions.html#cmdoption-arg-ReportMoreUnsafeFunctions>`_ is enabled,
50 the following functions are also checked:
52 - ``bcmp``, suggested replacement: ``memcmp``
53 - ``bcopy``, suggested replacement: ``memcpy_s`` if *Annex K* is available,
55 - ``bzero``, suggested replacement: ``memset_s`` if *Annex K* is available,
57 - ``getpw``, suggested replacement: ``getpwuid``
58 - ``vfork``, suggested replacement: ``posix_spawn``
60 Although mentioned in the associated CERT rules, the following functions are
61 **ignored** by the check:
63 ``atof``, ``atoi``, ``atol``, ``atoll``, ``tmpfile``.
65 The availability of *Annex K* is determined based on the following macros:
67 - ``__STDC_LIB_EXT1__``: feature macro, which indicates the presence of
68 *Annex K. "Bounds-checking interfaces"* in the library implementation
69 - ``__STDC_WANT_LIB_EXT1__``: user-defined macro, which indicates that the
70 user requests the functions from *Annex K.* to be defined.
72 Both macros have to be defined to suggest replacement functions from *Annex K.*
73 ``__STDC_LIB_EXT1__`` is defined by the library implementation, and
74 ``__STDC_WANT_LIB_EXT1__`` must be defined to ``1`` by the user **before**
75 including any system headers.
81 .. option:: ReportMoreUnsafeFunctions
83 When `true`, additional functions from widely used APIs (such as POSIX) are
84 added to the list of reported functions.
85 See the main documentation of the check for the complete list as to what
95 #ifndef __STDC_LIB_EXT1__
96 #error "Annex K is not supported by the current standard library implementation."
99 #define __STDC_WANT_LIB_EXT1__ 1
101 #include <string.h> // Defines functions from Annex K.
104 enum { BUFSIZE = 32 };
106 void Unsafe(const char *Msg) {
107 static const char Prefix[] = "Error: ";
108 static const char Suffix[] = "\n";
109 char Buf[BUFSIZE] = {0};
111 strcpy(Buf, Prefix); // warning: function 'strcpy' is not bounds-checking; 'strcpy_s' should be used instead.
112 strcat(Buf, Msg); // warning: function 'strcat' is not bounds-checking; 'strcat_s' should be used instead.
113 strcat(Buf, Suffix); // warning: function 'strcat' is not bounds-checking; 'strcat_s' should be used instead.
114 if (fputs(buf, stderr) < 0) {
120 void UsingSafeFunctions(const char *Msg) {
121 static const char Prefix[] = "Error: ";
122 static const char Suffix[] = "\n";
123 char Buf[BUFSIZE] = {0};
125 if (strcpy_s(Buf, BUFSIZE, Prefix) != 0) {
130 if (strcat_s(Buf, BUFSIZE, Msg) != 0) {
135 if (strcat_s(Buf, BUFSIZE, Suffix) != 0) {
140 if (fputs(Buf, stderr) < 0) {