145 lines
5.1 KiB
ReStructuredText
145 lines
5.1 KiB
ReStructuredText
|
.. title:: clang-tidy - bugprone-unsafe-functions
|
||
|
|
||
|
bugprone-unsafe-functions
|
||
|
=========================
|
||
|
|
||
|
Checks for functions that have safer, more secure replacements available, or
|
||
|
are considered deprecated due to design flaws.
|
||
|
The check heavily relies on the functions from the
|
||
|
**Annex K.** "Bounds-checking interfaces" of C11.
|
||
|
|
||
|
The check implements the following rules from the CERT C Coding Standard:
|
||
|
- Recommendation `MSC24-C. Do not use deprecated or obsolescent functions
|
||
|
<https://wiki.sei.cmu.edu/confluence/display/c/MSC24-C.+Do+not+use+deprecated+or+obsolescent+functions>`_.
|
||
|
- Rule `MSC33-C. Do not pass invalid data to the asctime() function
|
||
|
<https://wiki.sei.cmu.edu/confluence/display/c/MSC33-C.+Do+not+pass+invalid+data+to+the+asctime%28%29+function>`_.
|
||
|
|
||
|
`cert-msc24-c` and `cert-msc33-c` redirect here as aliases of this check.
|
||
|
|
||
|
Unsafe functions
|
||
|
----------------
|
||
|
|
||
|
If *Annex K.* is available, a replacement from *Annex K.* is suggested for the
|
||
|
following functions:
|
||
|
|
||
|
``asctime``, ``asctime_r``, ``bsearch``, ``ctime``, ``fopen``, ``fprintf``,
|
||
|
``freopen``, ``fscanf``, ``fwprintf``, ``fwscanf``, ``getenv``, ``gets``,
|
||
|
``gmtime``, ``localtime``, ``mbsrtowcs``, ``mbstowcs``, ``memcpy``,
|
||
|
``memmove``, ``memset``, ``printf``, ``qsort``, ``scanf``, ``snprintf``,
|
||
|
``sprintf``, ``sscanf``, ``strcat``, ``strcpy``, ``strerror``, ``strlen``,
|
||
|
``strncat``, ``strncpy``, ``strtok``, ``swprintf``, ``swscanf``, ``vfprintf``,
|
||
|
``vfscanf``, ``vfwprintf``, ``vfwscanf``, ``vprintf``, ``vscanf``,
|
||
|
``vsnprintf``, ``vsprintf``, ``vsscanf``, ``vswprintf``, ``vswscanf``,
|
||
|
``vwprintf``, ``vwscanf``, ``wcrtomb``, ``wcscat``, ``wcscpy``,
|
||
|
``wcslen``, ``wcsncat``, ``wcsncpy``, ``wcsrtombs``, ``wcstok``, ``wcstombs``,
|
||
|
``wctomb``, ``wmemcpy``, ``wmemmove``, ``wprintf``, ``wscanf``.
|
||
|
|
||
|
If *Annex K.* is not available, replacements are suggested only for the
|
||
|
following functions from the previous list:
|
||
|
|
||
|
- ``asctime``, ``asctime_r``, suggested replacement: ``strftime``
|
||
|
- ``gets``, suggested replacement: ``fgets``
|
||
|
|
||
|
The following functions are always checked, regardless of *Annex K* availability:
|
||
|
|
||
|
- ``rewind``, suggested replacement: ``fseek``
|
||
|
- ``setbuf``, suggested replacement: ``setvbuf``
|
||
|
|
||
|
If `ReportMoreUnsafeFunctions
|
||
|
<unsafe-functions.html#cmdoption-arg-ReportMoreUnsafeFunctions>`_ is enabled,
|
||
|
the following functions are also checked:
|
||
|
|
||
|
- ``bcmp``, suggested replacement: ``memcmp``
|
||
|
- ``bcopy``, suggested replacement: ``memcpy_s`` if *Annex K* is available,
|
||
|
or ``memcpy``
|
||
|
- ``bzero``, suggested replacement: ``memset_s`` if *Annex K* is available,
|
||
|
or ``memset``
|
||
|
- ``getpw``, suggested replacement: ``getpwuid``
|
||
|
- ``vfork``, suggested replacement: ``posix_spawn``
|
||
|
|
||
|
Although mentioned in the associated CERT rules, the following functions are
|
||
|
**ignored** by the check:
|
||
|
|
||
|
``atof``, ``atoi``, ``atol``, ``atoll``, ``tmpfile``.
|
||
|
|
||
|
The availability of *Annex K* is determined based on the following macros:
|
||
|
|
||
|
- ``__STDC_LIB_EXT1__``: feature macro, which indicates the presence of
|
||
|
*Annex K. "Bounds-checking interfaces"* in the library implementation
|
||
|
- ``__STDC_WANT_LIB_EXT1__``: user-defined macro, which indicates that the
|
||
|
user requests the functions from *Annex K.* to be defined.
|
||
|
|
||
|
Both macros have to be defined to suggest replacement functions from *Annex K.*
|
||
|
``__STDC_LIB_EXT1__`` is defined by the library implementation, and
|
||
|
``__STDC_WANT_LIB_EXT1__`` must be defined to ``1`` by the user **before**
|
||
|
including any system headers.
|
||
|
|
||
|
|
||
|
Options
|
||
|
-------
|
||
|
|
||
|
.. option:: ReportMoreUnsafeFunctions
|
||
|
|
||
|
When `true`, additional functions from widely used APIs (such as POSIX) are
|
||
|
added to the list of reported functions.
|
||
|
See the main documentation of the check for the complete list as to what
|
||
|
this option enables.
|
||
|
Default is `true`.
|
||
|
|
||
|
|
||
|
Examples
|
||
|
--------
|
||
|
|
||
|
.. code-block:: c++
|
||
|
|
||
|
#ifndef __STDC_LIB_EXT1__
|
||
|
#error "Annex K is not supported by the current standard library implementation."
|
||
|
#endif
|
||
|
|
||
|
#define __STDC_WANT_LIB_EXT1__ 1
|
||
|
|
||
|
#include <string.h> // Defines functions from Annex K.
|
||
|
#include <stdio.h>
|
||
|
|
||
|
enum { BUFSIZE = 32 };
|
||
|
|
||
|
void Unsafe(const char *Msg) {
|
||
|
static const char Prefix[] = "Error: ";
|
||
|
static const char Suffix[] = "\n";
|
||
|
char Buf[BUFSIZE] = {0};
|
||
|
|
||
|
strcpy(Buf, Prefix); // warning: function 'strcpy' is not bounds-checking; 'strcpy_s' should be used instead.
|
||
|
strcat(Buf, Msg); // warning: function 'strcat' is not bounds-checking; 'strcat_s' should be used instead.
|
||
|
strcat(Buf, Suffix); // warning: function 'strcat' is not bounds-checking; 'strcat_s' should be used instead.
|
||
|
if (fputs(buf, stderr) < 0) {
|
||
|
// error handling
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UsingSafeFunctions(const char *Msg) {
|
||
|
static const char Prefix[] = "Error: ";
|
||
|
static const char Suffix[] = "\n";
|
||
|
char Buf[BUFSIZE] = {0};
|
||
|
|
||
|
if (strcpy_s(Buf, BUFSIZE, Prefix) != 0) {
|
||
|
// error handling
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (strcat_s(Buf, BUFSIZE, Msg) != 0) {
|
||
|
// error handling
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (strcat_s(Buf, BUFSIZE, Suffix) != 0) {
|
||
|
// error handling
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (fputs(Buf, stderr) < 0) {
|
||
|
// error handling
|
||
|
return;
|
||
|
}
|
||
|
}
|