You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 42 Next »

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

  • No labels