Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The default global allocators will attempt to allocate sufficient storage for an object, and if successful, return a pointer with suitable alignment for that object. However, the default placement new operator enables the programmer to specify the memory in which an object being constructed will be located. A problem may arise if a pointer to this memory is misaligned with the platform's underlying architecture alignment restrictions. On several RISC architectures, such as PowerPC or IA64 (Itanium), access to misaligned objects might cause the program to terminate abnormally. This can also occur on IA32 CPUs which have been configured to fault on misaligned access.

Noncompliant Code Example

simply returns the given pointer back to the caller without guaranteeing that there is sufficient space in which to construct the object, or ensuring that the pointer meets the proper alignment requirements. The C++ Standard, [expr.new], paragraph 16, nonnormatively states [ISO/IEC 14882-2014]:

[Note: when the allocation function returns a value other than null, it must be a pointer to a block of storage in which space for the object has been reserved. The block of storage is assumed to be appropriately aligned and of the requested size. The address of the created object will not necessarily be the same as that of the block if the object is an array. —end note]

(This note is a reminder of the general requirements specified by The C++ Standard, [basic.stc.dynamic.allocation], paragraph 1, which apply to placement new operators by virtue of [basic.stc.dynamic], paragraph 3.)

Do not pass a pointer that is not suitably aligned for the object being constructed to placement new. Doing so results in an object being constructed at a misaligned location, which results in undefined behavior. Do not pass a pointer that has insufficient storage capacity for the object being constructed. Doing so may result in initialization of memory outside of the bounds of the object being constructed, which results in undefined behavior.

Noncompliant Code Example

In this noncompliant code example, a pointer to a short is passed to placement new, which is attempting to initialize a long. On architectures where sizeof(short) < sizeof(long), this results in undefined behaviorIn this noncompliant 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 operator new, the pointer a is pointing to an unaligned memory address. Writing val into a->i can cause the program to terminate abnormally.

Code Block
bgColor#FFcccc
langcpp
struct#include A {
  unsigned long i;
};

struct S<new>
 
void f() {
  unsigned char x;
  unsigned char B[sizeof(A)];
} short s;


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

Compliant Solution (Union)

Noncompliant Code Example

This noncompliant code example ensures that the long is constructed into a buffer of sufficient size. However, it does not ensure that the alignment requirements are met for the pointer passed into placement new. To make this more obvious, an additional local variable has been insertedIn the following compliant solution, a union is used to impose the alignment of unsigned long on the array B.

Code Block
bgColor#ccccff#FFcccc
langcpp
struct A#include <new>
 
void f() {
  unsigned long i;
};

union AlignedUnion {char c; // Used elsewhere in the function
  unsigned char Bbuffer[sizeof(Along)];

private:
  unsigned long _align_;
} algn;

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

Compliant Solution (G++)

 (buffer) long;
 
  // ...
}

Compliant Solution (std::aligned_storage)

This compliant solution ensures that the long is constructed into a buffer of sufficient size and with suitable alignment:The following is a compliant solution on a IA32 system using g++. In this solution, the ALIGN macro was added to ensure alignment when compiling with g++. In this case, it is used on B to make it aligned to 4, which is the alignment restriction for unsigned long.

Code Block
bgColor#ccccff
langcpp
#define ALIGN(X) __attribute__((aligned(X)))


struct A#include <new>
#include <type_traits>
 
void f() {
  unsignedchar long i;
};

struct S {
  unsigned char x;
  ALIGN(4) 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 (MSVC)

c; // Used elsewhere in the function
  std::aligned_storage<sizeof(long), alignof(long)>::type buffer;
  long *lp = ::new (&buffer) long;
 
  // ...
}

Compliant Solution (alignas)

In this compliant solution, the alignas declaration specifier is used to ensure the buffer is appropriately aligned for a long:The following is a compliant solution on a IA32 system using Microsoft Visual Studio. In this solution, the ALIGN macro was added to ensure alignment when compiling with Microsoft VS. 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.

Code Block
bgColor#ccccff
langcpp
#define ALIGN(X) _declspec(align(X))


struct A#include <new>
 
void f() {
  unsignedchar long i;
};

struct S {
  unsigned char x;
  ALIGN(4c; // Used elsewhere in the function
  alignas(long) unsigned char Bbuffer[sizeof(Along)];
} s;


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

Risk Assessment

Providing improperly-aligned pointers to placement new can result in undefined behavior, including abnormal termination.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MEM45-CPP

lowMedium

probableLikely

lowMedium

P6P8

L2

Automated Detection

Tool

Version

Checker

Description

    

Related Vulnerabilities

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

Related Guidelines

  

Bibliography

...

2014]5.3.4, "New"
3.7.4

...

, "Dynamic Storage Duration"