You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 57 Next »

Different alignments are possible for different types of objects. If the type-checking system is overridden by an explicit cast or the pointer is converted to a void pointer (void *) and then to a different type, the alignment of an object may be changed.

If the misaligned pointer is dereferenced, the program may terminate abnormally. The cast alone may cause a loss of information, even if the value is not dereferenced. For example, the following code is not guaranteed to work conforming C99 implementations, even though no pointers are dereferenced:

char c = 'x';
int *ip = (int *)&c; /* this can lose information */
char *cp = (char *)ip;
assert(cp == &c);    /* will fail on some conforming implementations */

On some implementations cp will not match &c.

As a result, if a pointer to one object type is converted to a pointer to a different object type, the second object type must not require stricter alignment than the first.

Noncompliant Code Example

C99 (and C90) allows a pointer to be cast into and out of void *. As a result, it is possible to silently convert from one pointer type to another without the compiler diagnosing the problem by storing or casting a pointer to void * and then storing or casting it to the final type. In this noncompliant code example, the type checking system is circumvented due to the caveats of void pointers.

char *loop_ptr;
int *int_ptr;

int *loop_function(void *v_pointer) {
  /* ... */
  return v_pointer;
}
int_ptr = loop_function(loop_ptr);

This example compiles without warning. However, v_pointer may be aligned on a one-byte boundary.

Compliant Solution

Because the input parameter directly influences the return value, and loop_function() returns an int *, the formal parameter v_pointer is redeclared to only accept int *.

int *loop_ptr;
int *int_ptr;

int *loop_function(int *v_pointer) {
  /* ... */
  return v_pointer;
}
int_ptr = loop_function(loop_ptr);

Another solution is to ensure that loop_ptr points to an object returned by malloc() because this object is guaranteed to be aligned properly for any need. However, this is a subtlety that is easily missed when the program is modified in the future. It is easier and safer to let the type system document the alignment needs.

Risk Assessment

Accessing a pointer or an object that is no longer on the correct access boundary can cause a program to crash or give wrong information, or may cause slow pointer accesses (if the architecture allows misaligned accesses).

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP36-C

low

probable

medium

P4

L3

Automated Detection

The LDRA tool suite V 7.6.0 can detect violations of this rule.

GCC Compiler can detect some violations of this rule when the -Wcast-align flag is used.

The EDG Front End to Compass/ROSE can detect some violations of this rule.

Compass/ROSE can detect violations of this rule. However, it does not flag explicit casts to void * and then back to another pointer type.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Other Languages

This rule appears in the C++ Secure Coding Standard as EXP36-CPP. Do not convert pointers into more strictly aligned pointer types.

References

[[Bryant 03]]
[[ISO/IEC 9899:1999]] Section 6.2.5, "Types"
[[ISO/IEC PDTR 24772]] "HFC Pointer casting and pointer type changes"
[[MISRA 04]] Rules 11.2 and 11.3


EXP35-C. Do not access or modify an array in the result of a function call after a subsequent sequence point      03. Expressions (EXP)      EXP37-C. Call functions with the arguments intended by the API

  • No labels