Created
June 2, 2011 16:40
-
-
Save mastbaum/1004770 to your computer and use it in GitHub Desktop.
An example of buffer overflows in C++ STL vectors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<iostream> | |
#include<vector> | |
#include<stdlib.h> | |
/** People sometimes get the false impression that because STL and iterators | |
* are fairly new additions to C++, they do sensible, commonplace things like | |
* bounds checking. | |
* | |
* This is sadly not the case, since preserving backwards-compatibility with C | |
* means preserving the loaded-gun-pointed-at-your-foot aspects, too. | |
* | |
* A semi-common related problem is to have doubles take on impossibly tiny | |
* values in somewhere in your code. Tiny doubles are usually the result of | |
* reinterpreting the ghost of an int as a double -- see end. | |
*/ | |
// YEAH! | |
class Awesome | |
{ | |
public: | |
int a; | |
double b; | |
std::string c; | |
Awesome() : a(5), b(42.0), c("woot") { } | |
}; | |
int main(int argc, char* argv[]) | |
{ | |
// how many doubles to dereference? | |
int n; | |
if(argc > 1) | |
n = atoi(argv[1]); | |
else | |
n = 10; | |
// soil up the memory space | |
std::vector<Awesome*> foo; | |
for(unsigned i = 0; i < 10 * n; i++) | |
foo.push_back(new Awesome()); | |
for(unsigned i = 0; i < 10 * n; i++) | |
delete foo[i]; | |
// think iterators are smart? think again. | |
std::vector<double> b(1); | |
std::vector<double>::iterator it; | |
// walk right off the end. a segfault is the best thing that could happen, | |
// since at least we'd know something went wrong. | |
for(it = b.begin(); it < b.end() + n; it++) | |
std::cout << *it << " "; | |
std::cout << "\n"; | |
// ints interpreted as doubles = tiny number | |
int fooInt = 42; | |
double *fooDouble = reinterpret_cast<double*>(&fooInt); | |
std::cout << "fooInt = " << fooInt << std::endl | |
<< "fooDouble = " << *fooDouble << std::endl; | |
} |
I don't think I will ever sleep soundly ever again. Thanks XD
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
nice one Andy