Versions Compared

Key

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

...

Do not call a deallocation function on anything other than  nullptr , or a pointer returned by the corresponding allocation function described by the following.

AllocatorDeallocator
global operator new()/newglobal operator delete()/delete
global operator new[]()/new[]global operator delete[]()/delete[]
class-specific operator new()/new class-specific operator delete()/delete
class-specific operator new[]()/new[] class-specific operator delete[]()/delete[]
placement operator new()N/A
allocator<T>::allocate()

allocator<T>::deallocate()

std::malloc(), std::calloc(),
std::realloc()
std::free()
std::get_temporary_buffer()std::return_temporary_buffer()
Page properties
hiddentrue

While the wording for std::return_temporary_buffer() in C++14 does not imply that you can pass a null pointer to it, that wording is superseded by the resolution for LWG 2072 (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2072) which does allow for null to be passed. Looking at all of the major implementations that I can get my hands on (MSVC STL, libc++, libstdc++, and stdcxx), it appears they all safely handle null pointer inputs as of 06/2015.

...

In this noncompliant code example, the local variable s1space is passed as the expression to the placement new operator. The resulting pointer of that call is then passed to ::operator delete(), resulting in undefined behavior due to ::operator delete() attempting to free memory that was not returned by ::operator new().

Code Block
bgColor#FFcccc
langcpp
#include <iostream>
 
struct S {
  S() { std::cout << "S::S()" << std::endl; }
  ~S() { std::cout << "S::~S()" << std::endl; }
};
 
void f() {
  alignas(struct S s1) char space[sizeof(struct S)];
  S *s2s1 = new (&s1space) S;
 
  // ...
 
  delete s2s1;
}

Compliant Solution (placement new())

This compliant solution removes the call to ::operator delete(), allowing s1 to be destroyed as a result of its normal object lifetime terminationinstead explicitly calling s1's destructor. This is one of the few times when explicitly invoking a destructor is warranted.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
 
struct S {
  S() { std::cout << "S::S()" << std::endl; }
  ~S() { std::cout << "S::~S()" << std::endl; }
};
 
void f() {
  alignas(struct S) s1;
  S *s2char space[sizeof(struct S)];
  S *s1 = new (&s1space) S;
 
  // ...

  s1->~S();
}

Noncompliant Code Example (Uninitialized delete)

...

Code Block
bgColor#FFcccc
langcpp
void f() {
  int *array = new int[10];
  // ...
  delete array;
}

Compliant Solution (array new[])

In the compliant solution, the code is fixed by replacing the call to delete with a call to delete [] to adhere to the correct pairing of memory allocation and deallocation functions.

Code Block
bgColor#ccccff
langcpp
void f() {
  int *array = new int[10];
  // ...
  delete[] array;
}

...

Passing a pointer value to a deallocation function that was not previously obtained by the matching allocation function results in undefined behavior, which can lead to exploitable vulnerabilities.

Rule

Severity

Likelihood

Remediation Cost

Detectable

Repairable

Priority

Level

MEM51-CPP

High

Likely

No

Medium

No

P18

P9

L1

L2

Automated Detection

Tool

Version

Checker

Description

Clang
Astrée

Include Page

Clang

Astrée_V

Clang

Astrée_V

clang-analyzer-cplusplus.NewDeleteLeaks
-Wmismatched-new-
invalid_dynamic_memory_allocation
dangling_pointer_use

Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC++-MEM51
Clang
Include Page
Clang_V
Clang_V
clang-analyzer-cplusplus.NewDeleteLeaks
-Wmismatched-new-delete
clang-analyzer-unix.MismatchedDeallocator 
Checked by clang-tidy, but does not catch all violations of this rule
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

ALLOC.

FNH

DF
ALLOC.TM

Free non-heap variable

ALLOC.LEAK

Double free
Type mismatch
LDRA tool suite
Leak
Helix QAC

Include Page

LDRA

Helix QAC_V

LDRA

Helix QAC_V

232 S, 236 S, 239 S, 407 S, 469 S, 470 S, 483 S, 484 S, 485 S, 64 D, 112 D

Partially implemented

C++2110, C++2111, C++2112, C++2113, C++2118, C++3337, C++3339, C++4262, C++4263, C++4264


Klocwork
Include Page
Klocwork_V
Klocwork_V
CL.FFM.ASSIGN
CL.FFM.COPY
CL.FMM
CL.SHALLOW.ASSIGN
CL.SHALLOW.COPY
FMM.MIGHT
FMM.MUST
FNH.MIGHT
FNH.MUST
FUM.GEN.MIGHT
FUM.GEN.MUST
UNINIT.CTOR.MIGHT
UNINIT.CTOR.MUST
UNINIT.HEAP.MIGHT
UNINIT.HEAP.MUST

LDRA tool suite
Include Page
LDRA_V
LDRA_V

232 S, 236 S, 239 S, 407 S, 469 S, 470 S, 483 S, 484 S, 485 S, 64 D, 112 D

Partially implemented

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_CPP-MEM51-a
CERT_CPP-MEM51-b
CERT_CPP-MEM51-c
CERT_CPP-MEM51-d


Use the same form in corresponding calls to new/malloc and delete/free
Always provide empty brackets ([]) for delete when deallocating arrays
Both copy constructor and copy assignment operator should be declared for classes with a nontrivial destructor
Properly deallocate dynamically allocated resources

Parasoft Insure++

Runtime detection
Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: MEM51-CPP

Checks for:

  • Invalid deletion of pointer
  • Invalid free of pointer
  • Deallocation of previously deallocated pointer

Rule partially covered.

PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V515, V554, V611, V701, V748, V773, V1066
Security Reviewer - Static Reviewer

Include Page
Security Reviewer - Static Reviewer_V
Security Reviewer - Static Reviewer_V

wcsdupCalledFully implemented
Parasoft C/C++test9.5MEM-06, MEM-12, MEM-28, MEM-29 Parasoft Insure++  Runtime detection PRQA QA-C++ 4.12110, 2111, 2112, 2113, 2118, 4262, 4263, 4264, 3337, 3339  
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S1232
 

Related Vulnerabilities

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

Related Guidelines

Bibliography

[Dowd 2007]"Attacking delete and delete [] in C++"
[Henricson 1997]Rule 8.1, "delete should only be used with new"
Rule 8.2, "delete [] should only be used with new []"
[ISO/IEC 14882-2014]

Subclause 5.3.5, "Delete"
Subclause 12.8, "Copying and Moving Class Objects"
Subclause 18.6.1, "Storage Allocation and Deallocation"
Subclause 20.7.11, "Temporary Buffers" 

[Meyers 2005]Item 16, "Use the Same Form in Corresponding Uses of new and delete"
[Seacord 2013]Chapter 4, "Dynamic Memory Management"
[Viega 2005]"Doubly Freeing Memory"

...


...

Image Modified   Image Modified   Image Modified