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

Compare with Current View Page History

« Previous Version 2 Next »

The placement new operator enables the programmer to specify the memory in which the object being instantiated will be allocated. A problem may arise when such a pointer is misaligned with the underlying architecture alignment restrictions. On several RISC architectures such as PowerPC or on IA64 (Itanium) or  Intel (IA32) CPUs which were configured to fault on unaligned access, access to unaligned objects might cause the program to terminate abnormally.  

Noncompliant Code Example

In this non compliant code a struct of type A is allocated on the memory region of s.B. The problem is that A has a member of type unsigned long which on IA32 systems is required to be aligned to 4. However B is an array of unsigned chars inside S and is not aligned to 4. After the call to new, the pointer a is pointing to an unaligned memory address. Writing val into a->i can cause the program to terminate abnormally.

int num = 5;
if (num * sizeof(SomeClass) > SIZE_MAX) {
  /* handle error */
}
SomeClass *sc = static_cast<SomeClass*>(malloc(sizeof(SomeClass)*num));
if (sc == NULL) {
  /* handle error */
}
// initialize sc array
// ...
// destroy sc
free(sc);

Compliant Solution

#ifdef WIN32
	#define ALIGN(X)_declspec(align(X))
#elif __GNUC__
	#define ALIGN(X) __attribute__((aligned(X)))
#else
    #define ALIGN(X) 
#endif

struct A{
	unsigned long i;
};

struct S{
	unsigned char x;
	unsigned char B[sizeof(A)];
}s;


int main()
{
	A *a = new(&s.B[0]) A;
	unsigned long val = 0xaabbccdd;
	a->i = val;
	return (0);
}

Compliant Solution

Vectors provide more safety and modularity than dynamically-allocated arrays

{
  int num = 5;
  if (num * sizeof(SomeClass) > SIZE_MAX) {
    /* handle error */
  }
  vector<SomeClass> sc(num);
  // ...
} // sc automatically deleted

  

Compliant Solution (1)

The following is a compliant solution on a IA32 system using either GCC or Microsoft's Visual Studio. In this solution the macro ALIGN was added to ensure alignment when compiling with both Microsoft VS compiler and g++ . The ALIGN macro calls either _declspec(align(#)) or _attribute_((aligned(#)))) to enforce alignment on a particular variable. In this case it is used on B to make it aligned to 4, which is the alignment restriction for unsigned long.

 

 

Compliant Solution (2)

In the following compliant solution a union is used to impose unsigned long's alignment on the array B.

Risk Assessment

Accessing a misaligned object may cause the program to terminate abnormally on several systems.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MEM45-CPP

low

probable

1

P2

L3

 

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Bibliography

[ISO/IEC 14882-2003] 3.7.4.1

  • No labels