
Software security in software development, especially considering the challenges it is currently facing (read article), must be prioritised. Thus, the ultimate goal must be to develop these systems already with a maximum of security and to detect errors as early as possible within the Software Development Lifecycles (SDLC). The standard procedure would be to conduct software tests. Dynamic testing is indispensable to recognise functional and structural difficulties of a system. However, there is one restriction: Tests can only detect errors, if a test case runs though the erroneous code, indicates an error message, which again leads to a result diverging from the expectation. A simple Buffer Overrun in C could look like this:
char buf[10];
…
buf[10] = ‘a‘ ;
Hereby, memory for an array of ten characters is allocated, the eleventh index of the array is accessed. The result of the access is not defined. In most cases, the character “a” will be written in some memory area next to the puffer and the previous content will be overwritten. Errors like these can be easily localised since the index-value in this example is hard coded. In practice, these indices stem from different sources such as user inputs, data, sensor signals and so on. If a Buffer Overrun occurs in the following example, depends on the length of the string to which the variable refers to:
int i;
char * s;
s = (char *) malloc(100);
…
i=0;while (s[i] != ‘\0‘)
i++;
If an error like a Buffer Overrun is displayed by dynamic software testing depends on two factors: Does the test case trigger the Buffer Overrun as a state violation? If yes: Does the state violation change the expected test result? The first point can be captured through very intensive testing where developers examine both the consequences of erroneous input and invalid values extensively.
The second condition is a little more difficult. Testing tools were not created to directly discover state violations. Possibly the test team is unable to recognise the easiest Buffer Overruns, as long as overwriting the Puffer does not result to a wrong output or to a program termination.
In order to recognise vulnerabilities to uncover such errors early in the SDLC, static code analysis is the best solution. Hereby, the preferred option are tools. Not only do they execute the code, but they also transfer it to a model. On the basis of the model, the analysis tool reviews all control and data streams and examines their correctness with so-called “checkers”. While creating the model from the code, the tool functions similar to a compiler, the code is transferred in an Intermediate Representation (IR). Since static analysis takes all states which the program could theoretically assume into account, potential errors can be detected with a significant increase of accuracy. Moreover, analysis tools provide much useful information helping developers to eradicate errors. Static code analyses either explicitly stipulates or strongly recommends standards and norms of software development for safety-critical applications such as ISO 26262 in the automotive industry or DO-178 B/C in the aerospace industry. Errors the analysis focuses on belong i.a. to to the classic gateways for Malware:
-> Buffer Overrun/Underrun
-> Command Injection
-> Integer Overflow of Allocation Size
-> SQL Injection
-> Non-constant Format String
A decisive advantage of this approach is that static code analysis does not require ready-to-be-executed code. Therefore, it can be deployed in all stages of the SDLC. Time and resources are scalable through the review-depths: Depending on the chosen checkers, the analysis requires more or less calculation time. Moreover, checkers of professional tools are individually definable to fulfil the specific requirements of the company. In the framework of agile development approaches such as Continuous Integration/ Continuous Deployment (CI/CD) which are more and more widespread in embedded-development, this could mean: At the workplace of the developers the first analysis takes place, before the integration into the mainline follows. To save time, the analysis can be restricted to focus on very typical errors or the compliance to programming guidelines. Another analysis instance could be working at the build-System. Furthermore, it would make sense to only conduct simple analysis during working hours to prevent influencing the productivity of the team negatively. More thorough examinations which require more calculation time could be executed during the night. Since professional analysis-tools such as Grammatech’s “Code Sonar”, in the German speaking countries distributed by Verifysoft Technology allow for a high amount of automatization, non-supervised analyses are easily possible.
Uncover Errors Early
Static code analysis as a fixed component of the SDLC can complement the testing process by reviewing the code early-on. Especially classic security gaps which are difficult to avoid especially in complex project can be recognised and fixed by the developer early-on. Above all high code quality is indispensable for embedded systems; not only because of the difficulties connected to updates and patches. In more and more areas embedded systems need to be certified according to strict standards. Hereby, many norms already expect the execution of static analysis either implicitly or explicitly. Similarly, even in domains where norms only play a minor role, the following rule applies: The earlier an error is detected, the less does its elimination cost.