I am trying to demonstrate a buffer overflow via an array index (when there isn't any bounds checking). What I am trying to do is change my bool authenticated = false to true by passing in a bad value.
I am using GCC 4.8.5
arrayVulnerability(int size)
{
int array[4];
bool authenticated = false;
for (int i = 0; i < size; i++)
{
array[i] = size;
}
}
My understanding is that my memory is set up as follows:
I was hoping that by passing an int larger than 4 I would be able to overwrite that position to true but it's not working. I'm curious if I have my memory misunderstood or if I am missing something?
Edit:
I printed out the locations as suggested and got the following:
bool authenticated = 0x7ffc4741612f
array[0] = 0x7ffc47416130
array[1] = 0x7ffc47416134
array[2] = 0x7ffc47416138
array[3] = 0x7ffc4741613c
array[4] = 0x7ffc47416140
So it looks like bool authenticated is before my array and my memory layout was wrong. I'm still confused about why it is before my array however.
The most likely implementation of automatic storage, the stack, grows downwards as objects are allocated. This means that array is allocated a certain address, and then authenticated is allocated a lower address. You can do some quick experiments to verify if this is the case. Either look at the state of an object defined before array, or print the addresses of the objects.
Related
I would like to have an array variable in private address space and dynamically initialise it with values.
Lets say I have the following code:
__kernel
void sample(__constant float * A){
__private float temp[2]; // Lets assume I know the size upfront.
for(int i = 0; i < 2; i++){
temp[i] = A[i];
printf("%.2f",temp[i]); // This works
}
printf("%.2f",temp[0]); // This does not work
}
What do you think the last printf statement should print assuming vector A contains [1,2,3,4]. I guess it would be reasonable to expect to have [1] printed, but it always returns 0. In my opinion though, after a bit of experiment, I guess the code in some manner associate the actual var 'i' with the value A[i] in array rather than the value (i.e., index) of the var 'i' contains.
Any idea on what I might be missing ?
I have the following piece of code, which is only half on the entire code:
// Declare map elements using an enumeration
enum entity_labels {
EMPTY = 0,
WALL
};
typedef entity_labels ENTITY;
// Define an array of ASCII codes to use for visualising the map
const int TOKEN[2] = {
32, // EMPTY
178 // WALL
};
// create type aliases for console and map array buffers
using GUI_BUFFER = CHAR_INFO[MAP_HEIGHT][MAP_WIDTH];
using MAP_BUFFER = ENTITY[MAP_HEIGHT][MAP_WIDTH];
//Declare application subroutines
void InitConsole(unsigned int, unsigned int);
void ClearConsole(HANDLE hStdOut);
WORD GetKey();
void DrawMap(MAP_BUFFER & rMap);
/**************************************************************************
* Initialise the standard output console
*/
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOut != INVALID_HANDLE_VALUE)
{
ClearConsole(hStdOut);
// Set window title
SetConsoleTitle(TEXT("Tile Map Demo"));
// Set window size
SMALL_RECT srWindowRect;
srWindowRect.Left = 0;
srWindowRect.Top = 0;
srWindowRect.Bottom = srWindowRect.Top + MAP_HEIGHT;
srWindowRect.Right = srWindowRect.Left + MAP_WIDTH;
SetConsoleWindowInfo(hStdOut, true, &srWindowRect);
// Set screen buffer size
COORD cWindowSize = { MAP_WIDTH, MAP_HEIGHT };
SetConsoleScreenBufferSize(hStdOut, cWindowSize);
}
/*************************************************************************/
/*************************************************************************
* Initialise the tile map with appropriate ENTITY values
*/
MAP_BUFFER tileMap;
for (unsigned int row = 0; row < MAP_HEIGHT; row++)
{
for (unsigned int col = 0; col < MAP_WIDTH; col++)
{
tileMap [row][col] = WALL;
}
}
Essentially the entire code is used to create a tile map and output it to screen but I'm attempting to make tileMap a dynamic array in runtime.
I have tried creating one down where the tileMap is being created.
I've tried creating one just after "entity_lables" are given the typedef "ENTITY".
I've tried creating one after the "MAP_BUFFER" and "GUI_BUFFER" become aliases.
But still I'm at a loss, I have no idea on how to successfully implement a dynamic array to tileMap, and I certainly don't know the best spot to put it.
Any help would be greatly appreciated.
The syntax you are using for defining your array is for a constant sized C array. In general you should shy away from C arrays unless the size of the data is determined at compile time(and never needs to change) and the array never leaves the scope(because a C array does not retain information on its own size.)
In place of constant or dynamically sized C arrays I would suggest to use the Vector container. The Vector is a dynamically sized container that fills up from the back, the last element you have added to
std::vector<std::vector<ENTITY>>
To add the vector container to your project add the line
#include <vector>
To fill the container your loop could look like:
MAP_BUFFER tileMap;
for (unsigned int row = 0; row < MAP_HEIGHT; row++)
{
std::vector<ENTITY> column; // A column of the tile map
for (unsigned int col = 0; col < MAP_WIDTH; col++)
{
column.push_back(WALL); // Add one element to the column
}
tileMap.push_back(column); // Add the column to the tile map
}
or you could initialize the Vector to the size you want at the beginning and use your current loop to assign the tile values:
using TILE_MAP = vector<vector<ENTITY>>;
// MAP_WIDTH x MAP_HEIGHT multidimensional vector
TILE_MAP tileMap(MAP_WIDTH, vector<ENTITY>(MAP_HEIGHT));
for (unsigned int row = 0; row < MAP_HEIGHT; row++)
{
for (unsigned int col = 0; col < MAP_WIDTH; col++)
{
tileMap [row][col] = WALL;
}
}
Calling an element of a vector after it has been filled has the same syntax as an array.
tileMap[2][4]
You can also check the length of the vector:
int rows = tileMap.size();
if( rows > 0 )
int columnsInRow0 = tileMap[0].size()
While you are at it you should look into other containers like Maps and Sets since they make your life easier.
Edit:
Since you want to know how to make a dynamic array not using a vector I will give you an answer: std::vector is the C++ defined dynamically sized array. C arrays will not change size after they are defined, vector will.
However I think you are asking about the ability to define runtime constant sized arrays. So I will explain what they are and why you should not use them.
When you define the C array you are probably getting a warning saying that the expression needs to be constant.
A C array is a pointer to the stack. And the implementation of the compiletime C array is that it needs to be a constant size at compile time.
int compiletimeArray[] = { 1, 2, 3 };
// turns out c arrays are pointers
int* ptr = compiletimeArray;
// prints 2
std::cout << compiletimeArray[1];
// prints 2
std::cout << ptr[1];
// prints 2
std::cout << *(compiletimeArray + 1);
// also prints 2
std::cout << *(ptr + 1); //move pointer 1 element and de-reference
Pointers are like a whiteboard with a telephone number written on it. The same kind of issues occur as with telephone numbers; number on whiteboard has been erased, number on whiteboard has changed, recipient does not exist, recipient changed their number, service provider running out of available numbers to give new users... Keep that in mind.
To get create a runtime constant sized array you need to allocate the array on the heap and assign it to a pointer.
int size = 4;
int* runtimeArray = new int[size]; // this will work
delete[] runtimeArray; // de-allocate
size = 8; // change size
runtimeArray = new int[size]; // allocate a new array
The main difference between the stack and heap is that the stack will de-allocate the memory used by a variable when the program exits the scope the variable was declared in, on the other hand anything declared on the heap will still remain in memory and has to be explicitly de-allocated or you will get a memory leak.
// You must call this when you are never going to use the data at the memory address again
// release the memory from the heap
delete[] runtimeArray; // akin to releasing a phone number to be used by someone else
If you do not release memory from the heap eventually you will run out.
// Try running this
void crashingFunction() {
while(true)
{
// every time new[] is called ptr is assigned a new address, the memory at the old address is not freed
// 90001 ints worth of space(generally 32 or 64 bytes each int) is reserved on the heap
int* ptr = new int[90001]; // new[] eventually crashes because your system runs out of memory space to give
}
}
void okFunction() {
// Try running this
while(true)
{
// every time new[] is called ptr is assigned a new address, the old is not freed
// 90001 ints worth of space is reserved on the heap
int* ptr = new int[90001]; // never crashes
delete[] ptr; // reserved space above is de-allocated
}
}
Why use std::vector? Because std::vector internally manages the runtime array.
// allocates for you
vector(int size) {
// ...
runtimeArray = new runtimeArray[size];
}
// When the vector exits scope the deconstructor is called and it deletes allocated memory
// So you do not have to remember to do it yourself
~vector() {
// ...
delete[] runtimeArray;
}
So if you had the same scenario as last time
void vectorTestFunction() {
// Try running this
while(true)
{
std::vector<int> vec(9001); // internally allocates memory
} // <-- deallocates memory here because ~vector is called
}
If you want to use a runtime constant array I suggest the std:array container. It is like vector in that it manages its internal memory but is optimized for if you never need to add new elements. It is declared just like vector but does not contain resizing functions after its constructor.
I have a short clip of C++ code that should theoretically work to create and return a torch.IntTensor object, but when I call it from Torch I get garbage data.
Here is my code (note this snippet leaves out the function registering, but suffice it to say that it registers fine--I can provide it if necessary):
static int ltest(lua_State* L)
{
std::vector<int> matches;
for (int i = 0; i < 10; i++)
{
matches.push_back(i);
}
performMatching(dist, matches, ratio_threshold);
THIntStorage* storage = THIntStorage_newWithData(&matches[0], matches.size());
THIntTensor* tensorMatches = THIntTensor_newWithStorage1d(storage, 0, matches.size(), 1);
// Push result to Lua stack
luaT_pushudata(L, (void*)tensorMatches, "torch.IntTensor");
return 1;
}
When I call this from Lua, I should get a [torch.IntTensor of size 10] and I do. However, the data appears to be either memory addresses or junk:
29677072
0
16712197
3
0
0
29677328
0
4387616
0
[torch.IntTensor of size 10]
It should have been the numbers [0,9].
Where am I going wrong?
For the record, when I test it in C++
for (int i = 0; i < storage->size; i++)
std::cout << *(storage->data+i) << std::endl;
prints the proper values.
As does
for (int i = 0; i < tensorMatches->storage->size; i++)
std::cout << *(tensorMatches->storage->data+i) << std::endl;
so it seems clear to me that the problem lies in the exchange between C++ and Lua.
So I got an answer elsewhere--the Google group for Torch7--but I'll copy and paste it here for anyone who may need it.
From user #alban desmaison:
Your problem is actually memory management.
When your C++ function return, you vector<int> is free, and so is its content.
From that point onward, the tensor is pointing to free memory and when you access it, you access freed memory.
You will have to either:
Allocate memory on the heap with malloc (as an array of ints) and use THIntStorage_newWithData as you currently do (the pointer that you give to newWithData will be freeed when it is not used anymore by Torch).
Use a vector<int> the way you currently do but create a new Tensor with a given size with THIntTensor_newWithSize1d(matches.size()) and then copy the content of the vector into the tensor.
For the record, I couldn't get it to work with malloc but the copying memory approach worked just fine.
I don't use C that much and I recently got confused about 2d array initialization problem. I need to debug somebody's code and stuck in the following(her original code):
const int location_num = 10000;
bool **location_matrix;
if (node_locations)
{
location_matrix = (bool **)malloc(location_num*sizeof(bool *));
if (!location_matrix)
{
cout<<"error 1 allocating location_matrix" << endl;
exit;
}
for (i=0; i<location_num; i++)
{
location_matrix[i] = (bool *) malloc(location_num*sizeof(bool ));
if (!location_matrix[i])
{
cout<<"error 2 allocating location_matrix" << endl;
exit;
}
for (j=0; j<location_num; j++)
location_matrix[i][j] = false;
}
}
I thought is was redundant, so I changed it to the following:
location_matrix[location_num][location_num] = { {false} };
However, segmentation fault happens at runtime.
My question is: how does the above code fail? If it looks right, what's the difference between dynamically allocation and static allocation? Is it just because the dimension might not be constant, so we need to do it dynamically?
Also, just for curiosity, how do I malloc 2d array that stores pointers? Thanks.
The change would likely require about 100MB (10,000 * 10,000 * 1) on the stack, so the segmentation fault was likely due to a stack overflow.
Edit I originally stated 400MB in the answer, but #Mooing Duck points out bool will likely be 1 byte. I was thinking the Win32 BOOL (for no real reason at all), which is typedefed to an int.
I actually don't see anything wrong with the code.
The following code doesn't work because location_matrix is not allocated:
location_matrix[location_num][location_num] = { {false} };
GCC will allow the following (as an extension):
bool location_matrix[location_num][location_num] = { {false} };
But it will blow your stack because 10000 x 10000 is too large.
Currently, your code uses dynamic allocation. That's the correct way to do it because the matrix is too large to be done as a static array (and may overrun the stack).
As for your last question, "how to make a 2d array that stores pointers": It can be done almost the same way as your current code. Just change bool to int*.
So a 2D array of NULL int pointers will look like this:
int ***location_matrix;
if (node_locations)
{
location_matrix = (int***)malloc(location_num*sizeof(int**));
if (!location_matrix)
{
cout<<"error 1 allocating location_matrix" << endl;
exit;
}
for (i=0; i<location_num; i++)
{
location_matrix[i] = (int**) malloc(location_num*sizeof(int*));
if (!location_matrix[i])
{
cout<<"error 2 allocating location_matrix" << endl;
exit;
}
for (j=0; j<location_num; j++)
location_matrix[i][j] = NULL;
}
}
The standard library is your friend.
#include <vector>
int
main()
{
int location_num = 1000;
std::vector<std::vector<bool> > location_matrix(location_num, std::vector<bool>(location_num, false));
}
Second, the array is likely too large to fit on the stack, so you'd need to dynamically allocate it -- but you can simplify the code as long as the difference between a 2-dimensional array and an array of pointers won't be an issue (as it would be if you needed to pass the array to a function or use pointer arithmetic with it).
You could use something like this:
bool (*location_matrix)[location_num];
location_matrix = (bool (*)[location_num])calloc( location_num,
location_num * sizeof(bool) );
...which allocates space for the whole two-dimensional array and gives a pointer to an array of bool arrays with location_num elements each.
I'm still getting my head around pointers and the like, so here goes...
Each client sends the position of the player correctly to the server.
On the server the data is then put into an array of structs (or points to structs?). The data of that array has also been verified to be correct.
The server then is meant to send all the data in that array back to each of the players
I would like to be able to send arrays from the server to the client (and back again) as the it is that approach I want to take in my head that I understand sort of (or arrays of pointers to structs?) eg, arrays of bullets and shooting, or other things.
I'm not worried about bandwidth at the moment or optimal code, that comes later when I understand it all better :)
Basically I've created a struct for my player:-
struct PlayerShip
{
unsigned int health;
unsigned int X;
unsigned int Y;
};
Then I've created an array (from the guidance of friends) that allows me to access the data of those structs (and typecast them as needed) (I think)
PlayerShip *playerArray[serverMaxClients];
for (int i = 0; i < serverMaxClients; i++)
{
playerArray[i] = new PlayerShip;
ZeroMemory(playerArray[i],sizeof(PlayerShip));
}
I recv data from all the connected players and feed it into the array
for (int slotIndex = 0; slotIndex < serverMaxClients; slotIndex++)
{
char szIncoming[1500];
ZeroMemory(szIncoming,1500);
int connectionStatus = recv(clientSocketArray[slotIndex], (char*)szIncoming,sizeof(szIncoming),0);
playerDataTemp = (PlayerShip*)szIncoming;
playerArray[slotIndex]->X = playerDataTemp->X;
playerArray[slotIndex]->Y = playerDataTemp->Y;
}
I print out the array and all the data is correct.
So the next step is to send that data back to the client.
I tried the following and a few variations of it, but I either get compile errors as I try to change variables into references and/or pointers (I still haven't had that epiphany moment where pointers and references suddenly makes sense), or the value comes out incorrectly. (the below case currently outputs an incorrect value)
for (int i = 0; i < serverMaxClients; i++)
{
char* outgoing = (char*)playerArray;
if (clientSlotTaken[i] == true)
{
send(clientSocketArray[i],outgoing,sizeof(playerArray),0);
}
int *valueCheck;
valueCheck = (int*)outgoing;
cout << "VALUE CHECK " << valueCheck << "\n";
delete outgoing;
}
The "Value Check" I'm expecting to be "100" as that should be player 1's health of 100 that was sent to the server earlier.
UPDATE
Okie now I'm starting to get my head around it a bit more.
playerArray is an array of pointers to structs. So I don't want to send the raw data from the array to the clients. I want to send the data of the structs to the players.
So I'm guessing I have to have a bit of code that creates a char array, which I populate with the data from all the player structs.
I tried the following but...
char outgoing[120];
PlayerShip *dataPopulator;
dataPopulator = &outgoing[0]; //Start at the begining of the array
for (int i=0; i < serverMaxClients; i++)
{
*dataPopulator = playerArray[i];
dataPopulator++;
}
I get the following errors
cannot convert 'char*' to 'PlayerShip*' in assignment|
no match for 'operator=' in '* dataPopulator = playerArray[i]'|
Thanks to Joriki, that help me understand it a bit more, but I still have a way to go :\ Still reading through lots of web pages that try to explain pointers and such
PlayerShip *playerArray[serverMaxClients];
declares an array of serverMaxClients pointers, each of which points to a PlayerShip structure.
Here
char* outgoing = (char*)playerArray;
you're referring to the address of this array of pointers, so your call to send will send a bunch of pointers, which is almost certainly not what you want. Also, here
delete outgoing;
you're trying to delete this array of pointers, which was allocated on the stack and not from the heap, so this might cause major problems; also, you're deleting the same pointer in every iteration.
I think the following comes closer to what you're intending to do:
for (int i = 0; i < serverMaxClients; i++)
{
char* outgoing = (char*)playerArray [i];
if (clientSlotTaken[i] == true)
{
send(clientSocketArray[i],outgoing,sizeof(PlayerShip),0);
}
int *valueCheck;
valueCheck = (int*)outgoing;
cout << "VALUE CHECK " << *valueCheck << "\n";
delete outgoing;
}
This sends the data in the PlayerShip structures, as opposed to just machine-dependent pointers to it, and it frees the memory allocated on the heap by "new PlayerShip", as opposed to the array of pointers to it allocated on the stack. Note also the added asterisk in the output statement for the value check; you were outputting a pointer instead of the value being pointed to. (Even if you'd added the asterisk, you would have just gotten an int cast of the first pointer in the array, rather than the health value in the PlayerShip structure it points to.)
I hope that helps; feel free to ask further questions in the comments if I haven't made it clear.
Update in response to ChiggenWingz' comments and udpate:
If you want to send all the data to each client, I see three options:
1) You can replace the send in my code with a loop:
if (clientSlotTaken[i] == true)
{
for (int j = 0;j < serverMaxClients;j++)
send(clientSocketArray[i],(char*)playerArray [j],sizeof(PlayerShip),0);
}
But I assume you're trying to avoid that since it may make the I/O less efficient.
2) You can do what you tried to do in your update. To resolve the errors you listed and make it work:
a) You need to cast the char* to a PlayerShip*, just like you had to cast the other way around in your earlier code.
b) In the copy assignment, you have a PlayerShip on the left, but a PlayerShip* on the right -- you need to dereference that pointer.
c) Using a fixed length like 120 is pretty dangerous; if you have more clients later, this could overflow; the size should be serverMaxClients * sizeof (PlayerShip).
d) "&outgoing[0]" is synonymous with "outgoing".
Putting that all together:
char outgoing[serverMaxClients * sizeof (PlayerShip)];
PlayerShip *dataPopulator;
dataPopulator = (PlayerShip*) outgoing; //Start at the begining of the array
for (int i=0; i < serverMaxClients; i++)
{
*dataPopulator = *playerArray[i];
dataPopulator++;
}
3) The best option I think would be to allocate all the PlayerShips together in one contiguous array instead of separately. You could do that either on the stack or on the heap, as you prefer:
a) On the heap:
PlayerShip *playerShips = new PlayerShip [serverMaxClients];
ZeroMemory (playerShips,serverMaxClients * sizeof(PlayerShip));
b) On the stack:
PlayerShip playerShips [serverMaxClients];
ZeroMemory (playerShips,sizeof(playerShips));
(The ZeroMemory call in a) would also work in b), but not the other way around.)
Now, independent of how you allocated the contiguous array, you can write the entire data to each client like this:
for (int i = 0; i < serverMaxClients; i++)
if (clientSlotTaken[i] == true)
send(clientSocketArray[i],(char *) playerShips,serverMaxClients * sizeof(PlayerShip),0);
(Again, in case b) you could replace the size calculation by sizeof(playerShips).
I hope that clarifies things further -- but feel free to ask more general questions about pointers if you're still confused :-)