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