If ptr
was allocated with an alignment returned from aligned_alloc()
and if realloc()
reallocates memory with a different alignment then, the behavior is undefined.
This rule only applies to compilers that conform to the (emerging) C1X standard [[Jones 09]].
Noncompliant Code Example
This noncompliant code example aligns ptr
to a 4096 byte boundary whereas the realloc()
function aligns the memory to a different alignment (assuming that the sizeof(double) = 8
and sizeof(float) = 4
.)
size_t size = 16; size_t alignment = 1 << 12; float *ptr; double *ptr1; ptr = aligned_alloc(align , size); ptr1 = realloc(ptr, size);
The resulting program has undefined behavior as the alignment that realloc()
enforces is different from aligned_alloc()
function's alignment.
Compliant Solution
This compliant solution checks that aligned_alloc()
has the same alignment as the alignment realloc()
function enforces on the memory pointed to by ptr
(again assuming that the sizeof(double) = 8
and sizeof(float) = 4
).
size_t size = 16; size_t alignment = 1 << 12; float *ptr; double *ptr1; ptr = aligned_alloc(align , size); if(align == alignof(ptr1)) { ptr1 = realloc(ptr, size); }
Implementation Details
When compiled with gcc version 4.1.2 and run on the x86_64-redhat-linux platform the following code:
#include <stdlib.h> #include <stdio.h> int main(void) { size_t size = 10; size_t align = 1 << 12; float *ptr; double *ptr1; if(posix_memalign((void **)&ptr, align , 8) != 0) { exit(0); } ptr[0] = 12.5; ptr[1] = 25.5; printf("memory aligned to %d bytes\n\n",align); printf("ptr[0] : %p = %f\n",ptr, ptr[0]); printf("ptr[1] : %p = %f\n\n",&ptr[1], ptr[1]); if((ptr1 = realloc((int *)ptr, 1024)) == NULL) { exit(0); } printf("After realloc(): \n"); printf("ptr1[0] : %p = %lf\n",ptr1, ptr[0]); printf("ptr1[1] : %p = %lf\n\n",&ptr1[1], ptr1[1]); free(ptr1); return 0; }
produces the following (unexpected) output.
memory aligned to 4096 bytes ptr[0] : 0xb43c000 = 12.500000 ptr[1] : 0xb43c004 = 25.500000 After realloc(): ptr1[0] : 0xb43c000 = 12.500000 ptr1[1] : 0xb43c008 = 0.000000 The value at ptr[1] remains the same after realloc() ptr[1] : 0xb43c004 = 25.500000
Risk Assessment
Improper alignment can lead to accessing arbitrary memory locations and write into it.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
MSC36-C |
medium |
probable |
medium |
P8 |
L2 |
References
[[Jones 09]] Section 7.21.3