Skip to end of metadata
Go to start of metadata

This guideline has not been reviewed recently and may be outdated. Please review it and comment to reflect any newly available information.

The reinterpret_cast operator is the least secure of the C++ typecasting operators. C++2004 section 5.2.10, paragraph 3 says:

The mapping performed by reinterpret_cast is implementation-defined. Note: it might, or might not, produce a representation different from the original value.

That said, the usual action of reinterpret_cast is to change the type, but leave the value unchanged.

Any class object may be accessed by a pointer to itself, or a pointer to one of its ancestor classes. If the object has multiple parents (or any of its parents have multiple parents), then a pointer to a base class might have a different value than a pointer to the object itself. As illustration, the following program:

#include <iostream>

using namespace std;

class Base1 {public: virtual ~Base1() {}};
class Base2 {public: virtual ~Base2() {}};
class Derived: public Base1, public Base2 {public: virtual ~Derived() {}};

int main() {
  Derived obj;
  Derived* dp = &obj;
  Base1* b1p = dp;
  Base2* b2p = dp;
  Derived* dps = static_cast<Derived*>( b2p);
  Derived* dpr = reinterpret_cast<Derived*>( b2p);
  cout << "dp  is " << static_cast<void*>( dp) << endl;
  cout << "dp == b1p ? " << (dp == b1p ? "yes" : "no") << endl;
  cout << "b1p is " << static_cast<void*>( b1p) << endl;
  cout << "dp == b2p ? " << (dp == b2p ? "yes" : "no") << endl;
  cout << "b2p is " << static_cast<void*>( b2p) << endl;
  cout << "dp == dps ? " << (dp == dps ? "yes" : "no") << endl;
  cout << "dps is " << static_cast<void*>( dps) << endl;
  cout << "dp == dpr ? " << (dp == dpr ? "yes" : "no") << endl;
  cout << "dpr is " << static_cast<void*>( dpr) << endl;
  return 0;
}

has the following output, when compiled using G++ 4.3.2 on Linux 2.6.27-11:

dp is 0x7fffa40ee9b0
dp == b1p ? yes
b1p is 0x7fffa40ee9b0
dp == b2p ? yes
b2p is 0x7fffa40ee9b8
dp == dps ? yes
dps is 0x7fffa40ee9b0
dp == dpr ? no
dpr is 0x7fffa40ee9b8

Clearly the base pointer b2p has a different value than the original dp pointer it was initialized from, although they do compare equally. The static_cast operator restores the original pointer value, but the reinterpret_cast operator preserves the new pointer value, and is regarded as different from the original dp value.

Note that this rule uses static_cast despite EXP13-CPP. Prefer dynamic_cast over static_cast over reinterpret_cast. While dynamic_cast would be safer static_cast is more illustrative for this example.

Risk Assessment

Improper casting can lead to programs that misinterpret data. If an attacker can manipulate this data, they may be able to execute arbitrary code.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP14-CPP

high

probable

low

P18

L1

Automated Detection

Tool

Version

Checker

Description

ECLAIR

1.2

CP1.EXP14

Fully implemented

LDRA tool suite9.7.1

 

241 S

Enhanced Enforcement

Parasoft C/C++test9.5CODSTA-CPP-09 
PRQA QA-C++4.13090 

Bibliography

[Dewhurst 03] Gotcha #38: Casting under Multiple Inheritance
[ISO/IEC 14882-2003] Sections 5.2.10