...
In this noncompliant example, the char pointer &c
is converted to the more strictly aligned int
pointer i_ptr
.:
Code Block | ||||
---|---|---|---|---|
| ||||
void f(void) { int *i_ptr; char c; i_ptr = (int *)&c; /* violation */ /* ... */ } |
...
In this compliant solution, the value referenced by the char
pointer c_ptr
has the alignment of type int
.:
Code Block | ||||
---|---|---|---|---|
| ||||
void f(void) { char *c_ptr; int *i_ptr; int i; c_ptr = (char *)&i; i_ptr = (int *)c_ptr; /* ... */ } |
...
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 *
.:
Code Block | ||||
---|---|---|---|---|
| ||||
int *loop_ptr; int *int_ptr; int *loop_function(int *v_pointer) { /* ... */ return v_pointer; } int_ptr = loop_function(loop_ptr); |
...
Many architectures require that pointers are correctly aligned when accessing objects larger than a byte. There are, however, many places in system code where you receive unaligned data (for example, the network stacks) that needs to be copied to a properly aligned memory location, such as in this noncompliant code example.:
Code Block | ||||
---|---|---|---|---|
| ||||
char *data; struct foo_header *tmp; struct foo_header *header; tmp = data + offset; memcpy(&header, tmp, sizeof(header)); if (header.len < FOO) /* ... */ |
...
This compliant solution does not use the foo_header
pointer.:
Code Block | ||||
---|---|---|---|---|
| ||||
char *data; struct foo_header header; memcpy(&header, data + offset, sizeof(header)); if (header.len < FOO) /* ... */ |
...
For objects declared on the stack, the C Standard provides alignas
to declare an object to have a stricter alignment. It can be used to resolve the following noncompliant code example.:
Code Block | ||||
---|---|---|---|---|
| ||||
char c = 'x'; int *ip = (int *)&c; /* this can lose information */ char *cp = (char *)ip; assert(cp == &c); /* will fail on some conforming implementations */ |
Compliant Solution
The This compliant solution uses alignas
to align the the character c
to the alignment of an integer. As a result, the two pointers point to equally aligned pointer types.:
Code Block | ||||
---|---|---|---|---|
| ||||
alignas(int) char c = 'x'; /* align c to the alignment of an int */ int *ip = (int *)&c; char *cp = (char *)ip; assert(cp == &c); /* both cp and &c point to equally aligned objects */ |
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Compass/ROSE | Can detect violations of this rule. However, it does not flag explicit casts to | ||||||||
| castexpr | Fully implemented. | |||||||
EDG | |||||||||
GCC |
| Can detect some violations of this rule when the | |||||||
| 94 S | Fully implemented. | |||||||
PRQA QA-C |
| 3305 | Fully implemented. |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
CERT C++ Secure Coding Standard | EXP36-CPP. Do not convert pointers into more strictly aligned pointer types |
ISO/IEC TR 24772:2013 | Pointer Casting and Pointer Type Changes [HFC] |
ISO/IEC TS 17961 (Draft) | Converting pointer values to more strictly aligned pointer types [alignconv] |
MISRA -CC:2012 | Rule 11.1 (required) Rule 11.2 (required) Rule 11.35 (advisory) Rule 11.7 (required) |
Bibliography
[Bryant 2003] | |
[ISO/IEC 9899:2011] | Section 6.3.2.3, "Pointers" |
[Walfridsson 2003] | Aliasing, Pointer Casts and GCC 3.3 |
...