Versions Compared

Key

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

When invoked by a new expression for a given type, the default global non-placement forms of C++ of operator new attempt to allocate sufficient storage for an object of the type and, if successful, return a pointer with alignment suitable for any object with a fundamental alignment requirement. However, the default placement new operator 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 [ISO/IEC 14882-2014], nonnormatively states the following:

...

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, including the overhead required for arrays. Doing so may result in initialization of memory outside of the bounds of the object being constructed, which results in undefined behavior

Finally, do not use placement new[] on any platform that does not specify a limit for the overhead it requires.

Noncompliant Code Example

...

The amount of overhead required by array new expressions is unspecified but ideally would be documented by quality implementations. The following compliant solution is specifically for the Clang and GNU GCC compilers, which guarantee that the overhead for dynamic array allocations is a single value of type size_t. (Note that this value is often treated as a "-1th" element in the array, so the actual space used may be larger.) To verify that the assumption is, in fact, safe, the compliant solution also overloads the placement new[] operator to accept the buffer size as a third argument and verifies that it is at least as large as not smaller than the total amount of storage required.

Code Block
bgColor#ccccff
langcpp
#include <cstddef>
#include <new>

#if defined(__clang__) || defined(__GNUG__)
  const size_t overhead = sizeof(size_t);
#else
  static_assert(false, "you need to determine the size of your implementation's array overhead");
  const size_t overhead = 0; // Declaration prevents additional diagnostics about overhead being undefined; the value used does not matter.
#endif

struct S {
  S();
  ~S();
};

void *operator new[](size_t n, void *p, size_t bufsize) {
  if (n <=> bufsize) {
    throw std::bad_array_new_length();
  }
  return p;
}

void f() {
  const size_t n = 32;
  alignas(S) unsigned char buffer[sizeof(S) * n + std::max(overhead, alignof(S))];
  S *sp = ::new (buffer, sizeof(buffer)) S[n];
 
  // ...
  // Destroy elements of the array.
  for (size_t i = 0; i != n; ++i) {
    sp[i].~S();
  }
}

...

Passing improperly aligned pointers or pointers to insufficient storage to placement new expressions can result in undefined behavior, including buffer overflow and abnormal termination.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MEM54-CPP

Medium

High

Likely

Medium

P9

P18

L2

L1

Automated Detection

Tool

Version

Checker

Description

Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC++-MEM54
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

LANG.MEM.BO

Buffer Overrun

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C++3119, C++3128, DF3520, DF3521, DF3522, DF3523


LDRA tool suite
Include Page
LDRA_V
LDRA_V

597 S

Enhanced Enforcement

Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_CPP-MEM54-a
CERT_CPP-MEM54-b

Do not pass a pointer that has insufficient storage capacity or that is not suitably aligned for the object being constructed to placement 'new'
An overhead should be used when an array of objects is passed to the placement 'new' allocation function

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: MEM54-CPPChecks for placement new used with insufficient storage or misaligned pointers (rule fully covered)
PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V752

Related Vulnerabilities

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

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]Subclause 3.7.4, "Dynamic Storage Duration"
Subclause 5.3.4, "New"
 
 


...

Image Modified Image Modified Image Modified