Like a compiler, CodeSonar® does a build of your code using your existing build environment. But, instead of creating object code, CodeSonar creates an abstract model of your program, capturing its syntax, call graphs, and control-flow graphs (CFGs). Then a synthesis phase, analogous to linking, generates a whole-program model, which is executed symbolically by CodeSonar's SmashProof™ analysis engine.
CodeSonar's SmashProof analysis engine performs an interprocedural exploration of program paths, reasoning about feasible paths, program variables and how they relate. CodeSonar models each procedure’s behavior, data, and side effects and then performs an interprocedural path exploration to catch tricky bugs that can result from complex interactions among procedures.
The exploration is path-sensitive, context-sensitive, and object-sensitive. When the path exploration encounters an anomaly, a warning is generated. The representations maintained by CodeSonar can become quite large, so a variety of strategies are employed to ensure scalability. For example, procedure summaries are refined and compacted during the analysis, and paths are explored in an order that minimizes paging. Another technique that improves performance is the use of advanced dataflow analysis to prune infeasible program paths from the exploration.
To see how CodeSonar fits into a typical workflow and to see its user interface, take the tour.
These are some of the checks that the CodeSonar analysis performs. Users can also use the CodeSonar API to add checks for custom warning classes.
- Buffer Overrun (example)
- A read or write to data after the end of a buffer.
- Leak (example)
- Dynamically allocated storage has not been freed.
- Null Pointer Dereference (example)
- An attempt to dereference a pointer to the address 0.
- Buffer Underrun
- A read or write to data before the beginning of a buffer.
- Type Overrun
- An overrun of a boundary within an aggregate type.
- Type Underrun
- An underrun of a boundary within an aggregate type.
- Divide By Zero
- An attempt to perform integer division where the denominator is 0.
- Double Free
- Two calls to free on the same object.
- Use After Free
- A dereference of a pointer to a freed object.
- Free Non-Heap Variable
- An attempt to free an object which was not allocated on the heap, such as a stack-allocated variable.
- Uninitialized Variable
- An attempt to use the value of a variable that has not been initialized.
- Dangerous Function Cast
- A function pointer is cast to another function pointer having an incompatible signature or return type.
- Delete[] Object Created by malloc
- An attempt to release memory obtained with malloc using delete[]
- Delete[] Object Created by new
- An attempt to release memory obtained with new using delete[]
- Delete Object Created by malloc
- An attempt to release memory obtained with malloc using delete
- Delete Object Created by new[]
- An attempt to release memory obtained with new[] using delete
- Free Object Created by new[]
- An attempt to release memory obtained with new[] using free
- Free Object Created by new
- An attempt to release memory obtained with new using free
- Missing Return Statement
- At least one path through a non-void return-type function does not contain a return statement.
- Redundant Condition
- Some condition is either always or never satisfied.
- Return Pointer To Local
- A procedure returns a pointer to one of its local variables.
- Return Pointer To Freed
- A procedure returns a pointer to memory that has already been freed.
- Unused Value
- A variable is assigned a value, but that value is never subsequently used on any execution path.
- Useless Assignment
- Some assignment always assigns the value that the variable being modified already has.
- Varargs Function Cast
- A varargs function pointer is cast to another function pointer having different parameters or return type.
- Ignored Return Value
- The value returned by some function has not been used.
- Free Null Pointer
- An attempt to free a null pointer.
- Unreachable Code
- Some of the code in a function is unreachable from the function entry point under any circumstances.
- Null Test After Dereference
- A pointer is NULL-checked when it has already been dereferenced.
- Format String
- A function that should have a format string passed in a particular argument position has been passed a string that either is not a format string or is from an untrusted source. (Potential security vulnerability.)
- Double Close
- An attempt to close a file descriptor or file pointer twice.
- TOCTTOU Vulnerability
- A time-of-check-to-time-of-use race condition that can create a security vulnerability.
- Double Lock
- An attempt to lock a mutex twice.
- Double Unlock
- An attempt to unlock a mutex twice.
- Try-lock that will never succeed
- An attempt to lock a mutex that cannot possibly succeed.
- Misuse of Memory Allocation
- Incorrect use of memory allocators.
- Misuse of Memory Copying
- Incorrect use of copying functions.
- Misuse of Libraries
- Misuse of standard library functions.
- User-Defined Bug Classes
- Checks for arbitrary bug classes can be implemented through the CodeSonar extension functions.
CodeSonar is integrated with the Common Weakness Enumeration (CWE). Warning classes are associated with the appropriate CWE IDs (if any) in the CodeSonar manual and in warning reports in the CodeSonar web GUI.