Abstract data types , private data types, and information hiding are not restricted to object-oriented languages like such as C++ and Java. These concepts can and They should be implemented created and used in C language programs as well.
Non-Compliant Code Example
Wiki Markup |
---|
This non-compliant code example is based on the managed string library developed by CERT \[[Burch 06|AA. C References#Seacord 06]\]. In this non-compliant example, the managed string type is defined in the include file "string_m.h" as follows: |
. Abstract data types are most effective when used with private (opaque) data types and information hiding.
Noncompliant Code Example
This noncompliant code example is based on the managed string library developed by CERT [Burch 2006]. In this example, the managed string type and the functions that operate on this type are defined in the string_m.h
header file as follows:
Code Block | ||||
---|---|---|---|---|
| ||||
Code Block | ||||
struct string_mx { size_t size; size_t maxsize; unsigned char strtype; char *cstr; }; typedef struct string_mx string_mx; /* Function declarations */ extern errno_t strcpy_m(string_mx *s1, const string_mx *s2); extern errno_t strcat_m(string_mx *s1, const string_mx *s2); /* ... */ |
The implementation of the string_
m mx
type is fully visible to the user of the data type , after including the "string_m.h
" file. Programmers are consequently more likely to directly manipulate the fields within the structure, violating the software engineering principles of information hiding and data encapsulation and increases increasing the probability of developing incorrect or non-portable nonportable code.
Compliant Solution
This compliant solution reimplements the string_mmx
type as a private type, hiding the implementation of the data type from the user of the managed string library. This can be accomplished the following manner. The To accomplish this, the developer of the private data type creates two include header files: an external "string_m.h
" include header file that is included by the user of the data type and an internal file that is included only included in files that implement the managed string abstract data eypetype.
In the external "string_m.h"
file, the string_mmx
type is declared as a pointer to a defined to be an instance of struct string_mx
, which in turn is declared as an incomplete type.:
Code Block | ||||
---|---|---|---|---|
| ||||
struct string_mx; typedef struct string_mx string_mx; /* Function declarations */ extern errno_t strcpy_m(string_mx *s1, const string_mx *s2); extern errno_t strcat_m(string_mx *s1, const string_mx *s2); /* ... */ |
In the "private" compilation unit internal header file, struct string_mx
is fully defined but non-not visible to a user of the API.data abstraction:
Code Block | ||||
---|---|---|---|---|
| ||||
struct string_mx { size_t size; size_t maxsize; unsigned char strtype; char *cstr; }; |
#include "Modules that implement the abstract data type include both the external and internal definitions, whereas users of the data abstraction include only the external string_m.h
" file. This allows the implementation of the string_mx
data type to remain private.
Risk Assessment
String handling functions defined in C99 Section 7.21 and elsewhere are susceptible to common programming errors that can lead to serious, exploitable vulnerabilities. Managed strings, when used properly, can eliminate many of these errors--particularly in new development.
The use of opaque abstract data types, though not essential to secure programming, can significantly reduce the number of defects and vulnerabilities introduced in code, particularly during ongoing maintenance.
Recommendation |
---|
Severity | Likelihood | Remediation Cost | Priority | Level |
---|
STR01-A
1 (low)
1 (unlikely)
1 (high)
P1
DCL12-C | Low | Unlikely | High | P1 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Axivion Bauhaus Suite |
| CertC-DCL12 | |||||||
LDRA tool suite |
| 104 D | Partially implemented | ||||||
Polyspace Bug Finder |
| CERT C: Rec. DCL12-C | Checks for structure or union object implementation visible in file where pointer to this object is not dereferenced (rule partially covered) | ||||||
Parasoft C/C++test |
| CERT_C-DCL12-a | If a pointer to a structure or union is never dereferenced within a translation unit, then the implementation of the object should be hidden |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Related Guidelines
MISRA C:2012 | Directive 4.8 (advisory) |
Bibliography
...
\[[Burch 06|AA. C References#Seacord 06]\]
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.2.5, "Types"
\[[Seacord 05a|AA. C References#Seacord 05a]\] Chapter 5, "Integer Security" Wiki Markup