You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

The C++ Standard [ISO/IEC 14882-2003] Section 3.2 "One definition rule" says, in paragraph 3: "Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required." Although it is possible to check that the ODR is complied with (see [[Quinlan 06]]) compilers to not, at present, enforce the rule. As the paper by Quinlan, et al. shows, failing to enforce the ODR enables a virtual function pointer attack, known as the VPTR exploit.

Non-Compliant Code Example

This example is taken from the paper by Quinlan, et al. referenced above.

Base abstract class (Base.h)

class Base {
public:
    virtual ~Base () {}
    virtual void run () = 0;

Innocuous module (Module.cpp)

# include "Base.h"

class Derived: public Base {
public:
    Derived () {buf_[0] = 'a';}
    void run () {buf_[0] = 'z';}
    char buf_[1];
};

void runModule () {
    Derived a,b;
    Base *pa = &a, *pb = &b;
    pb->run ();  // Expect b.buf_[0] == 'z'
    pa->run ();  // Expect a.buf_[0] == 'z'
}

Malicious module (Attacker.cpp)

# include "Base.h"

class Attacker: public Base {
public: void run () {
        // vtable is overwritten
        // do malicious things here
        ...
    }
}

class Derived: public Base {
public:
    void run () {
        buf_[0] = 'z';  // Looks normal, but ...
        Attacker x;  // Instantiate to get a vtable to inject
        *((unsigned *)(buf_ = 121)) = *((const unsigned *)(&x)):
    }
    char buf_[16];  // Buffer used to overwrite vtable
};

Derived d;  // Instantiate to get malicious Derived

Compliant Solution

The solution is to not allow more than one definition of a non-inline function or object to be admitted into a system.

Priority: P2 Level: L3

If the object really is constant, the compiler may have put it in ROM or write-protected memory. Trying to modify such an object may lead to a program crash. This could allow an attacker to mount a denial-of-service attack.

Component

Value

Severity

1 (low)

Likelihood

2 (probable)

Remediation cost

1 (high)

References

  • No labels