...
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
.)
Code Block | ||
---|---|---|
| ||
size_t size = 16; size_t resize = 1024; size_t alignment = 1 << 12; floatint *ptr; doubleint *ptr1; if((ptr = aligned_alloc(align , size)) == NULL) { exit(0); } if((ptr1 = realloc(ptr, size); resize)) == NULL) { exit(0); } |
The resulting program has undefined behavior as the alignment that realloc()
enforces is different from aligned_alloc()
function's alignment.
...
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
).
Code Block | ||
---|---|---|
| ||
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:
Code Block |
---|
#include <stdlib.h> #include <stdio.h> int main(void) { size_t size = 816; size_t re-sizeresize = 1024; size_t align = 1 << 12; floatint *ptr; int double *ptr1; if(posix_memalign((void **)&ptr, align , size) != 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%d\n",ptr, ptr[0]); printf("ptr[1] : %p = %f%d\n\n",&ptr[1], ptr[1]); if((ptr1 = realloc((int *)ptr, re-sizeresize)) == NULL) { exit(0); } printf("After realloc(): \n"); printf("ptr1[0] : %p = %lf%d\n",ptr1, ptrptr1[0]); printf("ptr1[1] : %p = %lf%d\n\n",&ptr1[1], ptr1[1]); free(ptr1); return 0; } |
...
Code Block |
---|
memory aligned to 4096 bytes ptr[0] : 0x39bf0000x1f8af000 = 12.500000 ptr[1] : 0x39bf0040x1f8af004 = 25.500000 After realloc(): ptr1[0] : 0x39be0100x1f8ae010 = 0.00000012 ptr1[1] : 0x39be018 = 0.000000 0x1f8ae014 = 25 |
Compliant Solution
This compliant solution implements an aligned realloc()
function. It allocates new memory of resize
bytes with an alignment equal to that of old memory and copies old memory into it. It then frees the old memory.
Code Block | ||
---|---|---|
| ||
size_t size = 16;
size_t resize = 1024;
size_t newsize;
int *ptr;
int *ptr1;
if((ptr = aligned_alloc(align , size)) == NULL) {
exit(0);
}
if((ptr1 = aligned_alloc(align , resize)) == NULL) {
exit(0);
}
newsize = MIN(size, resize);
if((memcpy(ptr1, ptr, newsize) == NULL) {
exit(0);
}
free(ptr);
|
Risk Assessment
Improper alignment can lead to accessing arbitrary memory locations and write into it.
...