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

Compare with Current View Page History

« Previous Version 38 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 example 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

Another noncompliant example that has been implemented on the x86_64-redhat-linux platform and compiled with gcc version 4.1.2 is as follows:

#include<stdlib.h>
#include<stdio.h>

int main() {
  size_t  size = 10;
  size_t align = 1 << 12;
  float *ptr;
  double *ptr1;

 posix_memalign((void **)&ptr, align , 4);

 if((ptr1 = realloc((int *)ptr, size)) == NULL) {
 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]);
 printf("After realloc(): \n");
 printf("ptr1[0]   : %p = %f\n",ptr1, ptr[0]);
 printf("ptr1[1]  : %p = %f\n\n",&ptr1[1], ptr1[1]);
 printf("The value at ptr[1] remains the same after realloc()\n");
 printf("ptr[1]  : %p = %f\n",((float *)ptr1+1),*((float *)ptr1+1));
 free(ptr1);
 return 0;
}

The noncompliant example 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 could 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