Global Sources
EE Times-Asia
Stay in touch with EE Times Asia
?
EE Times-Asia > Embedded
?
?
Embedded??

Static vs dynamic analysis for code devt (Part 2)

Posted: 06 Sep 2013 ?? ?Print Version ?Bookmark and Share

Keywords:dynamic code analysis? buffer overflow? virtual private network? VPN? deallocation?

A secure development process should also utilise dynamic code analysis in addition to static code analysis. A simple example demonstrates this need. The following code will be flagged as an error by a static source code analyser:

int *getval(void)
{
??return 0;
}
void foo(void)
{
??int *b = getval();
??*b = 0;
}

The pointer b is initialized by the return value from a function call that obviously returns a NULL pointer. Then b, the NULL pointer, is dereferenced. However, the following similar code may not be flagged as an error by a static source code analyser:

int fd;
int *getval(void)
{
??int *tmp;
??read(fd, &tmp, sizeof(tmp));
??return tmp;
}
void foo(void)
{
??int *b = getval();
??*b = 0;
}

In this example, b is also initialized by the return value from a function call. However, the source code provides no indication of potential return values from the function call. In particular, the return value is read from a file. While the file may well contain an invalid pointer, causing this program to crash, many static analysers will adopt a conservative approach (to minimise false positives) and will not assume anything specific about the externally read data.

Dynamic analysis uses code instrumentation or a simulation environment to perform checks of the code as it executes. For example, an instrumented program will have a check prior to the dereference of b which validates that b is not NULL. Or a simulator can validate all memory references to check for writes to address 0.

Some compilers have dynamic code analysis instrumentation available as a standard option. The development process should require that these checks be enabled at appropriate stages of development, testing, and integration.

For example, the Green Hills Software compiler has the option C check = memory, which causes the maximum amount of dynamic analysis instrumentation for various forms of memory errors, including NULL pointer dereferences.

The instrumented code performs the check and then calls a diagnostic function, provided by A library that is automatically linked to the program when using this option, which informs the user that a fault occurred as well as the type and location of the error within the source code, as follows:

> gcc myfile.c echeck=memory
> ./a.out
Nil pointer dereference on line 15 in file myfile.c

This is one example in which the program likely would have crashed, helping the developer Locate the program, even if dynamic analysis were not enabled. However, many other kinds of failures are far more insidious, leading to subtle corruptions that may go completely unnoticed or cause a downstream failure that is extremely difficult to trace back to its root cause.

Dynamic analysis detects the fault at its source, turning a thorny bug into a trivial one. Let's examine a few other examples of dynamic code analysis controls that developers should use during development and testing.

Buffer overflow
There are many forms of buffer overflow errors, many of which will not be caught by static analysis because the amount of data being written to a buffer is unknown at build time. The following is a simple example:

int an_array[10];
void a_func(int index)
{
??an_array[index] = 0;
}

If the parameter passed to a_func is a value read from a file or message queue by a caller to a_func, most static analysers will conservatively ignore this array reference. However, if index turns out to be a value greater than nine, a dynamic analyser will catch the fault, as shown here:

> gcc myfile.c echeck=bounds
> ./a.out
Array index out of bounds on line 50 in file myfile.c

Assignment bounds
The C and C++ programming languages(especially C)suffer from a lack of strong, compile time enforced-type safety that languages such as Ada and C# provide. However, quality coding standards as well as the use of static and dynamic analysis can provide reasonable compensation for these language limitations. Integer overflow is one risk of weak typing, as shown in the following example:

void assign(unsigned int p)
{
??static volatile unsigned short s;
??s=p;
}
void myfunc(void)
{
??assign(65536);
}

This code fragment is perfectly legal ANSIC; the assignment of p to s is defined to truncate p's value to fit s's type. In typical implementations, an unsigned short integer occupies 16 bits of storage, allowing values in the range of 0 to 65,535. However, in the example, a value just beyond this range is passed as the parameter p, clearly a programming error.

1???2???3???4?Next Page?Last Page



Article Comments - Static vs dynamic analysis for code ...
Comments:??
*? You can enter [0] more charecters.
*Verify code:
?
?
Webinars

Seminars

Visit Asia Webinars to learn about the latest in technology and get practical design tips.

?
?
Back to Top