Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: i added a new nce/cs but this may need some additional work

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.

According to C99 Section 6.3.2.3 p7:

A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined.

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:

...

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.

Noncompliant Code Example

Many architectures requires that pointers are correctly aligned when accessing objects bigger than a byte. There are however many places in system code where you receive unaligned data (e.g. the network stacks) that needs to be copied to a properly aligned memory location such as in this noncompliant code example.

Code Block
bgColor#FFCCCC

char *data;
struct foo_header *tmp;
struct foo_header *header;

tmp = data + offset;
memcpy(&header, tmp, sizeof(header));

if (header.len < FOO)
/* ... */

Unfortunately, the behavior is undefined when you assign an unaligned value to a pointer that points to a type that need to be aligned. An implementation may notice, for example, that tmp and header must be aligned, so it may use an inlined memcpy() that uses instructions that assumes aligned data.

Compliant Solution

This compliant solution does not use the foo_header pointer.

Code Block
bgColor#FFCCCC

char *data;
struct foo_header header;

memcpy(&header, data + offset, sizeof(header));

if (header.len < FOO)
/* ... */

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).

...

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

References

Wiki Markup
[Walfridsson 03] Krister Walfridsson. [Aliasing, pointer casts and gcc 3.3|http://mail-index.netbsd.org/tech-kern/2003/08/11/0001.html]. August, 2003.
\[[Bryant 03|AA. C References#Bryant 03]\]
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.2.5, "Types"
\[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "HFC Pointer casting and pointer type changes"
\[[MISRA 04|AA. C References#MISRA 04]\] Rules 11.2 and 11.3

...