StarlingX/Security/Banned C Functions
Prohibiting the use of banned functions is a good way to remove a significant number of potential code vulnerabilities from C and C++ code. This list is the compiled library of known bad functions that should be removed to reduce vulnerabilities. It is derived from experience with real-world security bugs and focuses primarily on functions that can lead to buffer overruns (reference: msdn).
Specifically, for Starling X, the main guidelines are that:
- Only functions in the standard C runtime library—libc—are mandated
- Unbounded functions are banned unless specifically noted
- Stack allocation functions are banned unless specifically approved by the project core
There is no requirement to retrofit existing upstream code to meet these guidelines. A summary of the policy is provided below.
|strcpy, wcscpy||unbounded, banned; use strncpy|
|strncpy||inspect for unterminated/truncated output|
|strcat, wcscat||unbounded, banned; use strncat|
|strncat||inspect for truncated output and buffer overflow|
|sprintf, vsprintf||unbounded, banned; use snprintf, vsnprintf|
|snprintf||inspect for result fitting in buffer: snprintf(buf, size, ...) < size|
|vsnprintf|| banned except with approval from core. requires detailed inspection to avoid va_list pitfalls.
vsnprint() is typically used for custom logging functionality. Given the flexibility of this function, it is easy to mismatch data types pushed on the stack for a va-list function and types pulled from the stack by the function. The core needs to ensure that the format matches the variables passed to avoid mismatches.
|strtok||unbounded, banned; use strtok_r or strsep|
|strtok_r, strsep||Inspect for terminated input buffer|
|scanf, sscanf, vscanf, vsscanf||banned except with approval of core. Requires detailed inspection to ensure field widths are specified. For unknown inputs, it is recommended to use strto* functions to avoid arithmetic overflows.|
|gets||unbounded, banned, use fgets() instead|
|ato*||banned, use equivalent strto* functions|
|*toa||Non-standard, inspect for output buffer length; prefer snprintf|
|strlen, wcslen||banned except static strings; use strnlen with max length constant|
|alloca|| banned except with approval of core. Requires detailed inspection to avoid stack overflow. In general, it is preferable to allocate from the heap using malloc() or calloc().
alloca() returns a pointer to a buffer located on the current thread's stack vs. the heap like malloc(). It's often used in cases where performance is especially important, but data length is unknown beforehand, because allocation is a simple matter of moving the stack pointer for the currently executing function. The dangers of using alloca() are stack space exhaustion or a buffer overflow which corrupts local variables.
If alloca() is used, the designer needs to understand that:
|Allowed w/Inspection||Banned||Banned w/Exceptions|