JavaScript is not currently enabled, but is required for full CodeSonar manual search and browse functionality.
If you are viewing this file in your hub's Web GUI, enable JavaScript in your browser: you will also need it for GUI functionality.
If you opened this file directly from disk, your browser may be directly suppressing JavaScript functionality: certain browsers perform this suppression on local files (but not files delivered by web servers) for security reasons.
| CodeSonar® 9.2p0 | CONFIDENTIAL | CodeSecure Inc |
This section describes the CodeSonar Extension API functions and macros. To use:
EDG_FRONTEND_OPTIONS_APPEND += -Icsonar_libmodels_path
For more information, see Implementing and Including Custom Checks with the Extension API.
| Library Model Management | ||
|---|---|---|
|
__CSURF_MARKER_LIBRARY_FUNCTION__
If this symbol is defined at the start of a function, the
function is treated as a library function.
|
||
| Attribute Handling | ||
|
CSONAR_DEFINE_ATTRIBUTE ( s )
Defines an attribute with name s.
|
||
|
CSONAR_DECLARE_ATTRIBUTE (
s )
Declares an attribute with name s.
|
||
|
csonar_replace_<PROCEDURE_NAME>
(same signature as <PROCEDURE_NAME>)
If csonar_replace_p
is defined for some procedure p, CodeSonar will
replace all calls to p from within a program with
calls to csonar_replace_p.
|
||
| int |
csonar_get_<NAME_OF_ATTRIBUTE>
(void *address)
Gets the value of the <NAME_OF_ATTRIBUTE>
attribute associated with address.
|
|
| void |
csonar_set_<NAME_OF_ATTRIBUTE>
( void *address, int
val )
Sets the value of the <NAME_OF_ATTRIBUTE>
attribute associated with address to val.
|
|
| void |
csonar_name_<NAME_OF_ATTRIBUTE>
( int val, const char *
const subject )
Uses the subject string to
associate a name with the val
value of the <NAME_OF_ATTRIBUTE>
attribute.
|
|
| Triggering Warnings | ||
| void |
csonar_trigger
( int lhs, const char
*const *op, int rhs,
const char *const warning_class )
Checks whether some trigger is satisfied, issues a warning
report if the check succeeds.
|
|
| void |
csonar_trigger_m ( int lhs,
const char *const op, int
rhs, const
char *const warning_class,
const char *const categories, csonar_warning_significance sig )
Checks whether some trigger is satisfied. If the check
succeeds, issues a warning report that includes categories for
the warning.
|
|
| void |
csonar_trigger_f (float lhs,
const char *const op, float
rhs, const
char *const warning_class,
const char *const categories, csonar_warning_significance sig )
Checks whether some condition on double-precision floating
point operands is satisfied, issues a warning report if the
check succeeds.
|
|
| void |
csonar_trigger_extended (
int cond, const char
*const *warning_class,
const char *const categories, csonar_warning_significance sig )
Checks whether some condition is satisfied, issues a warning
report if the check succeeds.
|
|
| General-Purpose Helpers | ||
| void |
csonar_important_global (
void *var )
Instructs CodeSonar to take particular care to track
*var.
|
|
| void * |
csonar_nullness_threshold (
void )
Gets the value of the NULL_POINTER
THRESHOLD preference.
|
|
| void |
csonar_escape (
void *obj )
Informs the CodeSonar analysis that the memory location
pointed to by obj may have
undergone arbitrary operations (such as assignment, freeing,
and so forth).
|
|
| float |
CSM_UNKNOWN_FLOAT ( void )
Provides a statically unknowable, non-negative float that
will be treated as benign.
|
|
| int |
CSM_UNKNOWN_INTEGER ( void )
Provides a statically unknowable, non-negative integer that
will be treated as benign.
|
|
| int |
CSM_SETS_ERRNO_TO_NONZERO (
void )
Models the setting of errno
to some non-zero value.
|
|
| int |
cs_untrusted_value ( void )
Provides a statically unknowable int value that will be treated as
adversarial.
|
|
| size_t |
cs_untrusted_size ( void )
Provides a statically unknowable size_t value that will be treated as
adversarial.
|
|
| int |
csonar_bounded_value ( int val,
int lb, int
ub )
Use to specify bounds on an int value.
|
|
| size_t |
csonar_bounded_size ( size_t val,
size_t lb, size_t
ub )
Use to specify bounds on a size_t value.
|
|
| int |
cs_untrusted_value_bound
(int lb, int
ub )
Provides a statically unknowable integer that will be treated
as adversarial, but whose value must lie within the specified
bounds.
|
|
| int |
cs_untrusted_untainted_value (
void )
Provides a statically unknowable integer that will be treated
as adversarial, but does not carry any taint.
|
|
| int |
csonar_warningclass_always_discarded_lm
( const char * class_name )
Check whether WARNING_FILTER settings are such that
instances of the specified warning class will always be
ignored.
|
|
| Allocator Modeling | ||
| CSONAR_MALLOC_FAILURE_BEHAVIOR |
csonar_malloc_failure_behavior
( void )
Gets the value of the MALLOC_FAILURE_BEHAVIOR preference.
|
|
| CSONAR_OPERATOR_NEW_FAILURE_BEHAVIOR |
csonar_operator_new_failure_behavior
( void )
Gets the value of the NEW_FAILURE_BEHAVIOR preference.
|
|
| For Dynamic Allocation After Initialization Check | ||
| void |
csonar_dyn_init ( void )
When it occurs in the definition of a function, informs the
CodeSonar analysis that the Dynamic
Allocation After Initialization check should treat that
function as part of the initialization phase.
|
|
| void |
csonar_entry_point ( void )
When it occurs in the definition of a function, informs the
CodeSonar analysis that the Dynamic
Allocation After Initialization check should treat that
function as an entry point for the program.
|
|
| For Concurrency Checks | ||
| void |
csonar_mutex_acquire ( void * mutex )
Informs the CodeSonar analysis that the thread now holds
mutex.
|
|
| void |
csonar_mutex_acquire_failed
( void * mutex )
Informs the CodeSonar analysis that the thread attempted to
acquire mutex but failed to do
so.
|
|
| CSONAR_MUTEX_FAILURE_BEHAVIOR |
csonar_mutex_failure_behavior
( void )
Gets the value of the MUTEX_FAILURE_BEHAVIOR preference.
|
|
| void |
csonar_mutex_pre_acquire (
void * mutex )
Every model of a lock-acquiring function should call this
before calling csonar_mutex_acquire() (and before calling
csonar_mutex_acquire_failed(), if
applicable), unless it calls csonar_mutex_pre_try_acquire() instead.
|
|
| void |
csonar_mutex_pre_release (
void * mutex )
Every model of a lock-releasing function should call this
before calling csonar_mutex_release(), unless it calls
csonar_mutex_pre_release_reent() instead.
|
|
| void |
csonar_mutex_pre_release_reent
( void * mutex )
Every model of a lock-releasing function should call this
before calling csonar_mutex_release() for
reentrant/recursive mutex.
|
|
| void |
csonar_mutex_pre_try_acquire
( void * mutex )
Every model of a try-lock function should call this before
calling csonar_mutex_acquire().
|
|
| void |
csonar_mutex_release ( void * mutex )
Informs the CodeSonar analysis that the thread no longer
holds mutex.
|
|
| void |
csonar_sighand_create (
void * (*fn)(void *), void * arg )
Informs the CodeSonar analysis that fn is a signal handler.
|
|
| void |
csonar_thread_create ( void * (*fn)(void
*), void * arg )
Informs the CodeSonar analysis that fn is a thread entry point.
|
|
| void |
csonar_relay_ignore (
void * var )
Instructs the CodeSonar data
race detector not to track accesses to var.
|
|
| void |
csonar_tls_set
( void ** key, void *
data )
Models thread-local storage write.
|
|
| void |
csonar_tls_get
( void ** key )
Models thread-local storage read.
|
|
| void |
csonar_blocking_function (
void )
Models blocking behavior.
|
|
| For Taint Analysis | ||
| int |
CSONAR_DEFINE_TAINT_SOURCE (
k )
Defines a taint kind with name k.
|
|
| int |
csonar_taint_source_<NAME_OF_KIND>
( void )
Provides a statically unknowable int value that is tainted with taint
kind <NAME_OF_KIND> and will be treated as
adversarial.
|
|
| size_t |
csonar_taint_size_source_<NAME_OF_KIND>
( void )
Provides a statically unknowable size_t value that is tainted with taint
kind <NAME_OF_KIND> and will be treated as
adversarial.
|
|
| int |
csonar_taint_source_any ( void )
Matches any taint kind except the built-in overflow/underflow
kinds.
|
|
| int |
csonar_taint_source_any_no_time
( void )
Matches any taint kind except time and the built-in overflow/underflow
kinds.
|
|
| int |
csonar_assert_taint_enabled
( void )
For use in distinguishing between the taint analysis phase
and other analysis phases.
|
|
| int |
csonar_assert_taint_disabled
( void )
For use in distinguishing between the taint analysis phase
and other analysis phases.
|
|
| void |
csonar_taint_clear_<NAME_OF_ATTRIBUTE>
( void * address )
Clears all taint from the value of the
<NAME_OF_ATTRIBUTE> attribute associated with
address.
|
|
| int |
csonar_taint_transfer (
v )
Generates an integer with unknown value and the same taint
status as v.
|
|
| int |
csonar_taint_sink ( int taint_kind,
val, const
char *const warning_class,
const char *const categories, csonar_warning_significance sig )
Checks whether a value has the specified kind of taint;
issues a warning report if so.
|
|
| int |
csonar_taint_mux ( int taint_phase_val, int other_phase_val )
Specify an int value whose
interpretation depends on the analysis phase.
|
|
| size_t |
csonar_taint_mux_size ( size_t
taint_phase_val, size_t other_phase_val )
Specify a size_t value whose
interpretation depends on the analysis phase.
|
|
| int |
csonar_taint_union2 ( a, b )
Generates an integer with unknown value and taint status
derived from that of the two arguments.
|
|
| int |
csonar_taint_union3 ( a, b,
c )
Generates an integer with unknown value and taint status
derived from that of the three arguments.
|
|
| int |
csonar_taint_union4 ( a, b,
c, d )
Generates an integer with unknown value and taint status
derived from that of the four arguments.
|
|
| int |
csonar_taint_union5 ( a, b,
c, d, e )
Generates an integer with unknown value and taint status
derived from that of the five arguments.
|
|
| int |
csonar_taint_union6 ( a , b,
c, d, e,
f )
Generates an integer with unknown value and taint status
derived from that of the six arguments.
|
|
| int |
csonar_taint_union7 ( a , b,
c, d, e,
f, g )
Generates an integer with unknown value and taint status
derived from that of the seven arguments.
|
|
| int |
csonar_taint_union8 ( a , b,
c, d, e,
f, g, h )
Generates an integer with unknown value and taint status
derived from that of the eight arguments.
|
|
| int |
csonar_taint_union9 ( a , b,
c, d, e,
f, g, h,
i )
Generates an integer with unknown value and taint status
derived from that of the nine arguments.
|
|
| int |
csonar_string_taint ( char * s )
Generates an integer with unknown value and taint status
derived from that of s.
|
|
| int |
csonar_wcstring_taint (
wchar_t * s )
Generates an integer with unknown value and taint status
derived from that of s.
|
|
enum CSONAR_MALLOC_FAILURE_BEHAVIOR{
|
enum CSONAR_MUTEX_FAILURE_BEHAVIOR{
|
enum CSONAR_OPERATOR_NEW_FAILURE_BEHAVIOR{
|
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
it *csonar_replace_my_iterator_New( void )
{...}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
|---|
| Parameter |
|
||
|---|---|---|---|
| Example |
CSONAR_DEFINE_ATTRIBUTE(open); |
||
| Note | Should occur in exactly one C file per attribute. |
| Parameter |
|
||
|---|---|---|---|
| Example |
CSONAR_DECLARE_ATTRIBUTE(open); |
| Parameters | As for <PROCEDURE_NAME>. |
|---|---|
| Returns | As for <PROCEDURE_NAME>. |
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int csonar_replace_add(int x, int y){
/* update necessary attributes */
/* ... */
return add(x,y)
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Note |
To maintain the same functionality as p,
csonar_replace_p
can call p with its intended arguments and return
its return value (if any). Calling p is not
obligatory, however, and programmers may wish to use
csonar_replace_p to
implement a model for p instead.
A CodeSonar project may contain multiple definitions of csonar_replace_p for a single p. At build time, CodeSonar will stack the definitions as follows:
|
| Parameter |
|
||
|---|---|---|---|
| Returns | The value of the <NAME_OF_ATTRIBUTE> attribute associated with address. | ||
| Example |
FILE *f;
...
if (csonar_get_open(f)){
...
|
| Parameter |
|
||||
|---|---|---|---|---|---|
| Returns | void | ||||
| Example |
FILE *f; ... csonar_set_open( f, 0 ); |
| Parameters |
|
||||
|---|---|---|---|---|---|
| Returns | void | ||||
| Example |
csonar_name_open( 0, "closed"); csonar_name_open( 1, "open"); |
||||
| Note | Calls to this function are treated as global definitions; it does not matter where they occur. |
| Parameters |
|
||||||||
|---|---|---|---|---|---|---|---|---|---|
| Returns | void | ||||||||
| Example |
FILE *f;
...
csonar_trigger(
csonar_get_open( f ),
"==",
0,
"Double Close" );
|
||||||||
| Notes |
The warning class created by this function will have an
empty categories
list and special significance value
"unspecified".
Warning Classes and TriggersAs part of setting up the analysis, CodeSonar creates a warning class for every occurrence of csonar_trigger(), csonar_trigger_extended(), csonar_trigger_m() , and csonar_taint_sink() whose warning_class argument does not correspond to an existing class. If there are several such calls with the same warning_class value, CodeSonar will set up the warning class based on the first call it encounters (note that this is not necessarily the first call in file order). When the trigger condition is satisfied during the analysis phase, the warning_class argument is used to retrieve the appropriate class for the warning. This means that if there are categories or a significance associated with a particular warning class, warnings of that class should always be triggered with a function that takes categories and significance arguments (that is, one of csonar_trigger_m(), csonar_trigger_extended(), csonar_taint_sink()), and the value of those arguments should be the same in every call – otherwise the class may be instantiated with an incorrect category list or an incorrect significance value. |
| Parameters |
|
||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Returns | void | ||||||||||||
| Example |
FILE *f; /* ... */ csonar_trigger_m( csonar_get_open( f ), "==", 0, "Double Close", "IO.DC;CWE:672;CWE:675", csws_reliability ); |
||||||||||||
| Note | See the note about warning
classes and triggers in the entry for csonar_trigger(). For floating point operands, use csonar_trigger_f(). |
| Parameters |
|
||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Returns | void | ||||||||||||
| Example |
double myfunc (double x){
csonar_trigger_f( x,
"<",
0.0,
"Negative myfunc argument",
"",
csws_reliability );
/* ... */
}
|
||||||||||||
| Note | See the note about warning
classes and triggers in the entry for csonar_trigger(). For integer operands, use csonar_trigger_m(). |
| Parameters |
|
||||||||
|---|---|---|---|---|---|---|---|---|---|
| Returns | void | ||||||||
| Example |
To generate CodeSonar warnings for assertions that can be
triggered in certain execution cases:
|
||||||||
| Note |
In general we recommend using csonar_trigger_m() rather than
csonar_trigger_extended()
unless the additional expressive power of the latter is
expressly required.
See also the note about warning classes and triggers in the entry for csonar_trigger(). |
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Example |
csonar_important_global(&foo); |
| Parameters | none |
|---|---|
| Returns | The value of the NULL_POINTER THRESHOLD parameter. |
| Example |
csonar_trigger_m( (int)p, "<", (int)csonar_nullness_threshold(), "Free Null Pointer", "ALLOC.FNP;CWE:590", csws_redundancy); |
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Example |
int *p = malloc( 4 );
csonar_escape(p);
i = *p; /* Uninitialized Variable NOT reported:
* *p might have been initialized */
|
||
| Note | The behavior of csonar_escape(void *p) is equivalent to that of ufname(void *p) for any undefined function ufname. In particular, it is not necessary to define previously-undefined functions solely in order to indicate this behavior through calls to csonar_escape(). |
| Parameters | none |
|---|---|
| Returns | A statically unknowable, non-negative float. |
| Example | Use cases are the floating-point counterparts of those for CSM_UNKNOWN_INTEGER. |
| Note |
This differs from cs_untrusted_value() in that CSM_UNKNOWN_FLOAT() is intended to
represent values that cannot be determined due to modeling
compromises while cs_untrusted_value() represents values
that are unknowable.
The analysis will treat CSM_UNKNOWN_FLOAT() values as benign: if there is a value that would allow a warning-triggering situation to be avoided then that warning is not issued. A CSM_UNKNOWN_FLOAT() value is always non-negative. |
| Parameters | none |
|---|---|
| Returns | A statically unknowable, non-negative integer. |
| Example | See examples for |
| Note |
This differs from cs_untrusted_value() in that CSM_UNKNOWN_INTEGER() is intended to
represent values that cannot be determined due to modeling
compromises while cs_untrusted_value() represents values
that are unknowable.
The analysis will treat CSM_UNKNOWN_INTEGER() values as benign: if there is a value that would allow a warning-triggering situation to be avoided then that warning is not issued. A CSM_UNKNOWN_INTEGER() value is always non-negative. |
| Parameters | none |
|---|---|
| Returns | A statically unknowable, tainted integer, with generic taint kind. Use cs_untrusted_value() to model a value that could be anything at all (including values that cause problems or errors). |
| Note | Use cs_untrusted_value() for int values and cs_untrusted_size() for size_t values. |
| Example | See examples for |
| Note |
This differs from CSM_UNKNOWN_INTEGER() in that
cs_untrusted_value() and
cs_untrusted_size() are
intended to represent values that are unknowable, while
CSM_UNKNOWN_INTEGER()
represents values that cannot be determined due to modeling
compromises.
The analysis will treat cs_untrusted_value()and cs_untrusted_size() values as adversarial: if there is a value that can lead to a warning being triggered, that value is assumed to be possible. The built-in models shipped with CodeSonar will never return cs_untrusted_value() or cs_untrusted_size() in the taint analysis phase: they will always return a value with a more-specific taint kind. Some built-in models do return cs_untrusted_value() or cs_untrusted_size() in other analysis phases. cs_untrusted_value() is preferable to rand() for modeling completely unknown values because rand() returns only non-negative values. |
| Parameters | none |
|---|---|
| Returns | void |
| Example | See examples for |
| Note | Calling this is usually preferable to setting errno directly to a specific value because it eliminates the need to account for every possible value that errno might be set to and every possible platform that might be used. |
| Parameters |
|
||||||
|---|---|---|---|---|---|---|---|
| Behavior | Adds lb≤val and val≤ub to the set of constraints imposed on val by the CodeSonar analysis. | ||||||
| Returns | An integer equal to val. | ||||||
| Note | Use csonar_bounded_value() for int values and csonar_bounded_size() for size_t values. | ||||||
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
char *strcadd(char *output, const char *inputstr)
{
int pos;
/* Invoke the strlen() model to carry out basic string checking on inputstr. */
strlen(inputstr);
/* For the taint analysis, model the output contents as unknown and
* tainted by inputstr. For the remainder of the analysis, model the
* output contents as untrusted. */
output[0] = csonar_taint_mux(csonar_string_taint(inputstr),
cs_untrusted_value());
/* For the taint analysis, model the length of the copied portion of
* inputstr as unknown amd tainted by inputstr; for the remainder of the analysis
* model the copied length as an untrusted value. In both cases, specify that the
* copied length is bounded below by 0 and above by the length of inputstr. */
pos = csonar_bounded_value(csonar_taint_mux(csonar_string_taint(inputstr),
cs_untrusted_value()),
0,
strlen(inputstr));
output[pos] = '\0';
return &output[pos];
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
See also the examples for: |
||||||
| Note |
If val was previously
constrained to lie below lb
or above ub, invoking
csonar_bounded_value(val, lb,
ub) or csonar_bounded_size(val, lb,
ub) leaves no possible
values for val, so is
equivalent to invoking abort().
Similarly, invoking csonar_bounded_value(val, lb, ub) or csonar_bounded_size(val, lb, ub) with lb>ub is always equivalent to invoking abort(). |
| Parameters |
|
||||
|---|---|---|---|---|---|
| Returns | An untrusted integer value v such that lb≤v≤ub. | ||||
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int mkstemp(char *template)
{
size_t len = strlen(template); /* The strlen() model will also carry out
* basic string checking on template. */
if( len == 0 )
return -1; /* Model the mkstemp() failure case. */
template[cs_untrusted_value_bound(0, len-1)] = 'c';
return open( template, 0 ); /* mkstemp() returns an open file descriptor
* on success: invoke the existing open() model
* to take advantage of the checking and
* relationship expression it provides. */
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
||||
| Note |
cs_untrusted_value_bound (x, y)
is equivalent to
csonar_bounded_value(cs_untrusted_value(), x, y)
|
| Parameters | none |
|---|---|
| Returns | An integer whose value is statically unknowable and will be treated as adversarial, but that does not carry any taint. |
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int _umask_s(int pmode, int * pOldMode)
{
*pOldMode = umask(pmode); /* Invoke the existing umask() model. */
return cs_untrusted_untainted_value(); /* Return value is untrusted but untainted. */
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Note |
cs_untrusted_untainted_value()
is equivalent to
|
| Parameters |
|
||||
|---|---|---|---|---|---|
| Returns |
|
||||
| Example |
The typical use case for csonar_warningclass_always_discarded_lm()
is one in which the checking for a particular warning class
involves state tracking that can cause problems for other
checks, and so should avoided unless explicitly required.
For example, suppose we have a custom class "Security Problem in myfunc" whose check involves such state tracking. We can use csonar_warningclass_always_discarded_lm() to guard the checking code: #define __CSURF_MARKER_LIBRARY_FUNCTION__ 1 /* Function that contains the checking code for class "Security Problem in myfunc". */ int do_very_expensive_check(int * a, int b){ if (/* [...] checking code */){ return 1; if (/* [...] more checking code */){ return 2; return 0; } /* CodeSonar will intercept calls to myfunc() and redirect them to csonar_replace_myfunc(). */ int csonar_replace_myfunc(int * intptr, int index) { /* Use the value of csonar_warningclass_always_discarded_lm("Security Problem in myfunc") to * guard the call to do_very_expensive_check(). */ if (!csonar_warningclass_always_discarded_lm("Security Problem in myfunc")){ csonar_trigger(do_very_expensive_check(intptr, index), "!=", 0, "Security Problem in myfunc") } /* Invoke the myfunc() function so its behavior can be analyzed. */ return myfunc(int * intptr, int index); } #undef __CSURF_MARKER_LIBRARY_FUNCTION__ |
||||
| Note |
Most users will never use this function.
In particular, it is not necessary to use this function to guard every call to a triggering function (such as csonar_trigger). |
| Parameters | none |
|---|---|
| Returns | A value of type CSONAR_MUTEX_FAILURE_BEHAVIOR, representing the setting of the MALLOC_FAILURE_BEHAVIOR preference. |
| Parameters | none |
|---|---|
| Returns | A value of type CSONAR_OPERATOR_NEW_FAILURE_BEHAVIOR, representing the setting of the NEW_FAILURE_BEHAVIOR preference. |
| Parameters | none |
|---|---|
| Returns | void |
| Example |
char * my_init_char(int n){
csonar_dyn_init();
return malloc(n);
}
int main(int argc, char *argv[]){
char *s = my_init_char(5); /* Dynamic Allocation After Initialization
NOT reported */
...
}
|
| Note |
When a function includes a call to csonar_entry_point(), all code that is
reachable from the function entry point will be examined
for the Dynamic
Allocation After Initialization check.
If you don't want to alter your source code directly, write an extension API code wrapper for your initialization function, include a call to csonar_dyn_init() in the wrapper, and include it in your CodeSonar project. User code can include multiple functions that call csonar_entry_point(). However, if the analysis encounters more than about 250 such functions, it will terminate. |
| Parameters | none |
|---|---|
| Returns | void |
| Example |
char * init_char(int n){
return malloc(n);
}
int mymain(void){
csonar_entry_point();
char *s = init_char(5); /* Dynamic Allocation After Initialization
reported */
...
}
|
| Note |
CodeSonar will automatically treat functions main() and init() as entry points: you do not
need to use csonar_entry_function() in these
functions.
If you don't want to alter your source code directly, write an extension API code wrapper for your entry function, include a call to csonar_entry_function() in the wrapper, and include it in your CodeSonar project. User code can include multiple functions that call csonar_entry_function(). However, if the analysis encounters more than about 250 such functions, it will terminate. |
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Note |
If a model for a lock-acquiring function does not call an
existing concurrency model, it should call this function.
|
||
| Example |
See also the csonar_mutex_pre_try_acquire()
example.
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int mylock(mymutex_t *m){
int retval = CSM_UNKNOWN_INTEGER(); /* Use CSM_UNKNOWN_INTEGER() to model failure
* as a random occurrence that cannot be
* detected statically. */
csonar_mutex_pre_acquire(m); /* Call csonar_mutex_pre_acquire() before
* calling csonar_mutex_acquire() or
* csonar_mutex_acquire_failed(). */
if( csonar_mutex_failure_behavior() == CSONAR_MXFB_DOESNT_FAIL || retval == 0 )
/* The failure case should not occur if
* MUTEX_FAILURE_BEHAVIOR is set to DOESNT_FAIL -
* use csonar_mutex_failure_behavior() to check. */
{
csonar_mutex_acquire(m); /* Call csonar_mutex_acquire() on success path. */
return 0;
}
else
{
csonar_mutex_acquire_failed(m); /* Call csonar_mutex_acquire_failed() on failure
* path. */
return retval;
}
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Note |
Use in models for lock-acquisition functions that have
failure cases.
|
||
| Example | See csonar_mutex_acquire() example. |
| Parameters | none |
|---|---|
| Returns | A value of type CSONAR_MUTEX_FAILURE_BEHAVIOR, representing the setting of the MUTEX_FAILURE_BEHAVIOR preference. |
| Note | Any call to csonar_mutex_acquire_failed() will generally be guarded by a test of csonar_mutex_failure_behavior(). |
| Example | See csonar_mutex_acquire() example. |
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Notes | csonar_mutex_pre_acquire() and csonar_mutex_pre_try_acquire() are responsible for pre-acquisition checking on mutex. In particular, they check that mutex is available for acquisition by the thread. Every call to csonar_mutex_acquire() should be preceded by a call to one of these two functions. | ||
| Example | See csonar_mutex_acquire() example. |
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Notes | csonar_mutex_pre_release() and csonar_mutex_pre_release_reent() are responsible for pre-release checking on mutex. In particular, they check that the thread holds mutex. Every call to csonar_mutex_release() should be preceded by a call to one of these two functions. | ||
| Example | See csonar_mutex_release() example. |
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Notes | csonar_mutex_pre_release() and csonar_mutex_pre_release_reent() are responsible for pre-release checking on mutex. In particular, they check that the thread holds mutex. Every call to csonar_mutex_release() should be preceded by a call to one of these two functions. | ||
| Example | See csonar_mutex_release() example. |
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Notes | csonar_mutex_pre_acquire() and csonar_mutex_pre_try_acquire() are responsible for pre-acquisition checking on mutex. In particular, they check that mutex is available for acquisition by the thread. Every call to csonar_mutex_acquire() should be preceded by a call to one of these two functions. | ||
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int mytrylock(mymutex_t *m){
int retval = CSM_UNKNOWN_INTEGER(); /* Use CSM_UNKNOWN_INTEGER() to model failure
* as a random occurrence that cannot be
* detected statically. */
csonar_mutex_pre_try_acquire(m); /* Call csonar_mutex_pre_try_acquire() before
* calling csonar_mutex_acquire(). */
if( retval == 0 )
{
csonar_mutex_acquire(m); /* Call csonar_mutex_acquire() on success path. */
return 0;
}
return retval;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Parameter |
|
||
|---|---|---|---|
| Returns | void | ||
| Note |
If a model for a lock-releasing function does not call an
existing concurrency model, it should call this function.
|
||
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int myunlock(mymutex_t *m){
int retval = CSM_UNKNOWN_INTEGER(); /* Use CSM_UNKNOWN_INTEGER() to model failure
* as a random occurrence that cannot be
* detected statically. */
csonar_mutex_pre_release(m); /* Call csonar_mutex_pre_release() on
* all branches, and before any call to
* csonar_mutex_release().
* If m is reentrant or recursive, call
* csonar_mutex_pre_release_reent() instead. */
if( csonar_mutex_failure_behavior() == CSONAR_MXFB_DOESNT_FAIL || retval == 0 )
/* The failure case should not occur if
* MUTEX_FAILURE_BEHAVIOR is set to DOESNT_FAIL -
* use csonar_mutex_failure_behavior() to check. */
{
csonar_mutex_release(m); /* Call csonar_mutex_release() on success path. */
return 0;
}
return retval;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Parameter |
|
||||
|---|---|---|---|---|---|
| Returns | void | ||||
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
my_thread_t *my_signal_handler(void * (*f)(void *)){
int retval = CSM_UNKNOWN_INTEGER(); /* Use CSM_UNKNOWN_INTEGER() to model failure
* as a random occurrence that cannot be
* detected statically. */
if (retval){
csonar_sighand_create(f, NULL); /* Call csonar_sighand_create() on success path. */
}
return (my_thread_t *)retval;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
||||
| Note | CodeSonar esssentially treats signal handlers as a special kind of thread. Models for interrupt handlers with similar properties should also call csonar_sighand_create(). |
| Parameter |
|
||||
|---|---|---|---|---|---|
| Returns | void | ||||
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
my_thread_t *my_thread_create(void * (*f)(void *)){
int retval = CSM_UNKNOWN_INTEGER(); /* Use CSM_UNKNOWN_INTEGER() to model failure
* as a random occurrence that cannot be
* detected statically. */
if (retval){
csonar_thread_create(f, NULL); /* Call csonar_thread_create() on success path. */
}
return (my_thread_t *)retval;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Parameter |
|
||
|---|---|---|---|
| Returns | void |
| Parameter |
|
||||
|---|---|---|---|---|---|
| Returns | void |
| Parameter |
|
||
|---|---|---|---|
| Returns | void * |
| Parameters | none |
|---|---|
| Returns | void |
| Note | Blocking functions can take a long time to return; many wait for external events of some kind. |
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
void my_big_io_function(void){
csonar_blocking_function(); /* Call csonar_blocking_function() to indicate that
* my_big_io_function() is a blocking function and
* should not be called inside a critical section.*/
read_big_input();
write_big_output();
return;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Parameter |
|
||
|---|---|---|---|
| Example |
CSONAR_DEFINE_TAINT_SOURCE(telephone); |
||
| Note |
Should occur in exactly one C file per taint kind.
In most cases we recommend using the built-in taint kinds rather than defining new ones, so that you can take advantage of existing checking and infrastructure. For example, it may be appropriate to use the existing network taint kind rather than defining a new telephone kind. |
| Parameters | none |
|---|---|
| Returns | A statically unknowable value that is tainted with taint kind <NAME_OF_KIND> and will be treated as adversarial. |
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
char *_cgets(char *buffer)
{
int len;
/* _cgets() reads a string from the console, so model the space
* required to accommodate the read string plus additional information as
* having taint kind file. Upper and lower bounds on this value
* are entailed by the _cgets() specification. */
len = csonar_bounded_value(csonar_taint_source_file(),
2,
buffer[0] + 2 );
/* The string contents also have taint kind file. */
buffer[2] = csonar_taint_source_file();
buffer[len] = '\0'; /* The tainted len value determines the position of the null terminator... */
buffer[1] = len; /* ...and is also written to buffer[1]. */
return &buffer[2];
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Note |
Use csonar_taint_source_k() for
int values and
csonar_taint_size_source_k()
for size_t values.
These functions have two main uses.
csonar_taint_source_k() and csonar_taint_size_source_k()are defined for
k ∈ {built
in taint kinds} ∪ {kinds defined with CSONAR_DEFINE_TAINT_SOURCE(
k) }
|
| Parameters | none |
|---|---|
| Returns | A value that matches any taint kind (including user-defined ones) except add_overflow, mult_overflow, sub_underflow and truncation_overflow. |
| Example | See example for csonar_taint_sink(). |
| Note | csonar_taint_source_any() is provided for use in taint_kind arguments to csonar_taint_sink(). It is not suitable for other uses. |
| Parameters | none |
|---|---|
| Returns | A value that matches any taint kind (including user-defined ones) except time, add_overflow, mult_overflow, sub_underflow and truncation_overflow. |
| Example | csonar_taint_source_any_no_time() is used in the same way as csonar_taint_source_any() (see example). |
| Note | csonar_taint_source_any_no_time() is provided for use in taint_kind arguments to csonar_taint_sink(). It is not suitable for other uses. |
| Parameters | none |
|---|---|
| Returns | void |
| Example |
The standard usage for csonar_assert_taint_enabled() and
csonar_assert_taint_enabled() is with the
following idiom.
if( CSM_UNKNOWN_INTEGER() ) { csonar_assert_taint_enabled(); /* model code to be analyzed during the taint analysis phase */ } else { csonar_assert_taint_disabled(); /* model code to be analyzed during the other analysis phases */ } } |
| Parameters | none |
|---|---|
| Returns | void |
| Example | See the csonar_assert_taint_enabled() example. |
| Parameters |
|
||
|---|---|---|---|
| Returns | void | ||
| Example |
Suppose we have a function MySQLDetaint() that takes a string S
and carries out some sequence of operations before
returning S′, which is derived from S but guaranteed to be
safe for use in an SQL query.
Then we can write csonar_replace_MySQLDetaint() to express this property:
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
char * csonar_replace_MySQLDetaint(char *s){
char *rv;
rv = MySQLDetaint(s); /* Call the MySQLDetaint() function so its
* behavior can be analyzed. */
csonar_taint_clear_int(rv); /* The "int" attribute of an address is an alias
* for the memory contents at that address, so
* this clears taint from rv. */
return rv;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Parameters |
|
||
|---|---|---|---|
| Returns |
An integer.
|
||
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int wctomb(char *mbchar, wchar_t wchar){
int len;
if( !mbchar ) /* wctomb() returns zero on null wchar. */
return 0;
if( CSM_UNKNOWN_INTEGER() ) /* wctomb() returns -1 on error. */
{
CSM_SETS_ERRNO_TO_NONZERO();
return -1;
}
/* The number of chars required to represent wchar is
* known to be either 0 or 1; the model instructs the analysis
* to regard this number as untrusted and - for the taint
* analysis - having the same taint status as wchar. */
len = csonar_bounded_value(csonar_taint_mux(csonar_taint_transfer(wchar),
cs_untrusted_value()),
0,
1 );
/* The output written to mbchar is generated from wchar,
* so has the same taint status as wchar. */
mbchar[0] = csonar_taint_transfer(wchar);
mbchar[len] = csonar_taint_transfer(wchar);
return len + 1; /* Model success-case return value. */
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Parameters |
|
||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Returns | void | ||||||||||
| Example |
This model for sethostid()
triggers a warning of class "Tainted Configuration
Setting" if the value of the hostid parameter is tainted with any
taint kind (other than add_overflow, mult_overflow, sub_underflow, and truncation_overflow, which are not
included by csonar_taint_source_any()).
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int sethostid(long hostid)
{
csonar_taint_sink( csonar_taint_source_any(),
hostid,
"Tainted Configuration Setting",
"CWE:15",
csws_security );
if( CSM_UNKNOWN_INTEGER() )
{
CSM_SETS_ERRNO_TO_NONZERO();
return -1;
}
gethostid_hostid = hostid;
return 0;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
||||||||||
| Note | See the note about warning classes and triggers in the entry for csonar_trigger(). |
| Parameters |
|
||||
|---|---|---|---|---|---|
| Returns |
A value whose interpretation varies depending on the
analysis phase.
|
||||
| Note | Use csonar_taint_mux() for int values and csonar_taint_mux_size() for size_t values. | ||||
| Example |
This model for atoi()
returns a value generated by csonar_taint_mux().
Note also call to strlen(s): this lets the atoi() model take advantage of the comprehensive string-related bug checking provided by the strlen() model.
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int atoi(const char *s)
{
int rv;
rv = csonar_taint_mux(csonar_string_taint(s),
cs_untrusted_value());
strlen(s);
CSM_SETS_ERRNO();
return rv;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
See also the examples for |
| Parameters |
|
||
|---|---|---|---|
| Returns |
An integer.
|
||
| Example |
#define __CSURF_MARKER_LIBRARY_FUNCTION__ 1
int swscanf_s(wchar_t *s, const wchar_t *fmt, ... )
{
int ret;
wcslen( s );
wcslen( fmt );
ret = csonar_taint_mux(
csonar_taint_union2(csonar_wcstring_taint( fmt ),
csonar_wcstring_taint( s )),
cs_untrusted_value());
if( ret < -1 ) for(;;);
if( CSM_UNKNOWN_INTEGER() && ret == -1 )
CSM_SETS_ERRNO_TO_NONZERO();
return ret;
}
#undef __CSURF_MARKER_LIBRARY_FUNCTION__
|
| Parameters |
|
||
|---|---|---|---|
| Returns |
An integer.
|
||
| Example | See the examples for |
| Parameters |
|
||
|---|---|---|---|
| Returns |
An integer.
|
||
| Example | See the csonar_taint_union2() example. |
To report problems with this documentation, please visit https://support.codesecure.com/.