This required moving files around in the repository and shifting from a master.adoc structure to _topic_map.yml, etc. README and Makefile modified slightly to reflect new build process
53 lines
2 KiB
Text
53 lines
2 KiB
Text
|
|
:experimental:
|
|
|
|
[[sect-Defensive_Coding-C-Other]]
|
|
== Other C-related Topics
|
|
|
|
[[sect-Defensive_Coding-C-Wrapper-Functions]]
|
|
=== Wrapper Functions
|
|
|
|
Some libraries provide wrappers for standard library functions.
|
|
Common cases include allocation functions such as
|
|
`xmalloc` which abort the process on
|
|
allocation failure (instead of returning a
|
|
`NULL` pointer), or alternatives to relatively
|
|
recent library additions such as `snprintf`
|
|
(along with implementations for systems which lack them).
|
|
|
|
In general, such wrappers are a bad idea, particularly if they
|
|
are not implemented as inline functions or preprocessor macros.
|
|
The compiler lacks knowledge of such wrappers outside the
|
|
translation unit which defines them, which means that some
|
|
optimizations and security checks are not performed. Adding
|
|
`__attribute__` annotations to function
|
|
declarations can remedy this to some extent, but these
|
|
annotations have to be maintained carefully for feature parity
|
|
with the standard implementation.
|
|
|
|
At the minimum, you should apply these attributes:
|
|
|
|
* If you wrap function which accepts are GCC-recognized format
|
|
string (for example, a `printf`-style
|
|
function used for logging), you should add a suitable
|
|
`format` attribute, as in <<ex-Defensive_Coding-C-String-Functions-format-Attribute>>.
|
|
|
|
* If you wrap a function which carries a
|
|
`warn_unused_result` attribute and you
|
|
propagate its return value, your wrapper should be declared
|
|
with `warn_unused_result` as well.
|
|
|
|
* Duplicating the buffer length checks based on the
|
|
`__builtin_object_size` GCC builtin is
|
|
desirable if the wrapper processes arrays. (This
|
|
functionality is used by the
|
|
`-D_FORTIFY_SOURCE=2` checks to guard
|
|
against static buffer overflows.) However, designing
|
|
appropriate interfaces and implementing the checks may not
|
|
be entirely straightforward.
|
|
|
|
For other attributes (such as `malloc`),
|
|
careful analysis and comparison with the compiler documentation
|
|
is required to check if propagating the attribute is
|
|
appropriate. Incorrectly applied attributes can result in
|
|
undesired behavioral changes in the compiled code.
|