VNX-1098: Data Element containing Pointer Item without Proper Copy Control Element
A C++ class whose destructor releases a raw pointer (delete, delete[], free) but which declares no copy constructor, so the implicit shallow copy leads to a double free (rule of three).
| Field | Value |
|---|---|
| Rule ID | VNX-1098 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | C++ |
| CWE | CWE-1098 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | cpp rule-of-three memory double-free cwe-1098 |
| Source | internal/sast/rules/vnx-1098.rego |
Overview
VNX-1098 maps to CWE-1098: Data Element containing Pointer Item without Proper Copy Control Element. It reports the destructor of a C++ class that owns memory through a raw pointer, releasing it with delete, delete[] or free(), when no copy constructor for that class is declared anywhere in the scanned files.
Why This Matters
Without a user-declared copy constructor the compiler generates one that copies the pointer, not what it points to. Pass the object by value, return it, or put it in a std::vector, and two objects own the same memory: the first destructor frees it and the second frees it again, or reads it after it was freed.
Not reported: classes with a copy constructor, including a deleted one (Name(const Name&) = delete), classes that declare a move constructor or move assignment (which suppresses the implicit copy), classes marked non-copyable (boost::noncopyable, DISALLOW_COPY_AND_ASSIGN, Q_DISABLE_COPY), destructors that release nothing, and comments.
What Gets Flagged
class Buffer {
public:
explicit Buffer(std::size_t n) : data_(new char[n]), size_(n) {}
~Buffer() { delete[] data_; } // FLAGGED: no Buffer(const Buffer&)
private:
char* data_;
std::size_t size_;
};
Session::~Session() // FLAGGED
{
delete user_;
}
Remediation
- Hold the memory in
std::unique_ptr,std::vectororstd::stringand drop the destructor (rule of zero). - Otherwise define the copy constructor and copy assignment to deep-copy, or delete them (
= delete). - For a confirmed false positive, add a
// vulnetix-ignore: VNX-1098comment on the line.
References
- CWE-1098: Data Element containing Pointer Item without Proper Copy Control Element
- C++ Core Guidelines C.21: define or delete all default operations
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-1098
// nosec vnx-1098
Or record an ignore rule: vulnetix ignore add --rule vnx-1098 --reason "...". See Suppressing findings.