Defending against stack overflow by user scripts - c++

C++ has limited stack space but no way for functions to check whether there's enough space left for them to run. I don't know what to do about this when writing script bindings.
For example:
class Container : Widget {
void addChild(WidgetPtr child) { ... }
void draw(Canvas& canvas) {
for (auto child : m_children) {
child.draw();
}
}
};
A malicious script can do this to crash the program:
var a = new Container()
for (i = 0; i < 10000000; i++) {
var b = new Container()
a.addChild(b)
a = b
}
a.draw() // 10000000 nested calls ---> stack overflow
There's also callback problem:
void doSomething(std::function<void()> callback) {
callback();
}
If wrapped using something like this:
ScriptValue doSomething_Wrapper(ScriptArgs args) {
doSomething([&]() { args[0].callAsFunction(); });
}
Crashed using:
function badCallback() { doSomething(badCallback) }
doSomething(badCallback)
...
doSomething_Wrapper
doSomething
ScriptValue::callAsFunction
...
doSomething_Wrapper
doSomething
ScriptValue::callAsFunction
...
BOOM!
What's the most idiomatic way to defend against this with least inconvenience?
What do browsers written in C++ (Firefox, Chrome) do?
What can I do not to introduce a vulnerability like this by accident?

While a "malicious" script could cause a stack overflow, like you describe, it can´t harm the program more than causing crashes that way (at least on modern OS where the stack limit is actually checked and therefore it´s safe against overwrites of other important data).
If it´s critical that the program is running all the time, another process has to monitor it (and restart it if necessary. Not only because stack overflows, there are many more potential problems.).
Other than that, there isn´t much one can do if the OS stack is used. Dynamically allocating a large memory block for a single pointer in the stack and doing the whole memory management manually in this block is possible, but maybe impractical.
About eg. FIrefox: At least parts of the program are using an own memory management (but I´m not sure if it is relevant for plugins, scripts etc.). Additionally, there is a separate process plugin-container.exe (at least on Windows), and killing won´t kill Firefox (only the plugin part like Flash etc. won´t work anymore and the user gets a message about plugin crashing).

Related

Recovering from out of memory failure

I am using a memory pool to create a lot of objects. All my objects derive from a Base class which has its new/delete over ridden to use my memory pool, basically they call pool.allocate(size).
What I would like to do is when the pool runs out of memory (there is still available memory in the system to function) I would like to set everything back to the beginning. I am thinking of setting a label right after main and goto label when allocation fails, reset the pool and start again.
All non stack allocation are handled by the memory pool. Is this a sensible way to achieve this? Are there gonna be any problems down the line?
EDIT:
This is running on an embedded platform so no OS no exceptions. I am trying to achieve a controlled restart instead of a crash from out of memory. Pool is big enough to hold calculations, I am trying to have a controlled crash in case some functions goes awry.
There is no state to be saved from run to run. I am trying to achive the process of hitting the reset button with software. So I can reset back to start of main notify the app about the restart.
I once did a similar thing using setjmp()/longjmp(). It's not perfect or devoid of problems, but, for the most part it works. Like:
jmp_buf g_env;
int main()
{
int val = setjmp(g_env);
if (val) {
// restarting, do what you need to do
}
// initialize your program and go to work
}
/// where you want to restart:
longjmp(g_env, 101); /// 101 or some other "error" code
This is a goto really, so, remember to do any cleanup yourself.
The first thing which comes in mind is throwing an exception. This is actually how default implementation of operator new behaves: it throws std::bad_alloc.
goto will work only if whole your program is limited to a single function. I see possible implementation of main as follows:
int main(int argc, const char* argv[]) {
while(true) {
try {
do_things(argc, argv);
} catch(const MyBadAlloc& ex) {
do_cleanup();
continue;
}
}
}

Segmentation Fault and RAII

It's more a philosophical type of question.
In C++ we have nice shiny idiom - RAII. But often I see it as incomplete. It does not well aligns with the fact that my application can be killed with SIGSEGV.
I know, I know, programms like that are malformed you say. But there is sad fact that on POSIX (specifically Linux) you can allocate beyond physical memory limits and meet SIGSEGV in the middle of the execution, working with correctly allocated memory.
You may say: "Application dies, why should you care about those poor destructors not being called?". Unfortunately there are some resources that are not automatically freed when application terminates, such as File System entities.
I am pretty sick right now of designing hacks, breaking good application design just to cope with this. So, what I am asking is for a nice, elegant solution to this kind of problems.
Edit:
It seems that I was wrong, and on Linux applications are killed by a kernel pager. In which case the question is still the same, but the cause of application death is different.
Code snippet:
struct UnlinkGuard
{
UnlinkGuard(const std::string path_to_file)
: _path_to_file(path_to_file)
{ }
~UnlinkGuard() {
unlink();
}
bool unlink() {
if (_path_to_file.empty())
return true;
if (::unlink(_path_to_file.c_str())) {
/// Probably some logging.
return false;
}
disengage();
return true;
}
void disengage() {
_path_to_file.clear();
}
private:
std::string _path_to_file;
};
void foo()
{
/// Pick path to temp file.
std::string path_to_temp_file = "...";
/// Create file.
/// ...
/// Set up unlink guard.
UnlinkGuard unlink_guard(path_to_temp_file);
/// Call some potentially unsafe library function that can cause process to be killed either:
/// * by a SIGSEGV
/// * by out of memory
/// ...
/// Work done, file content is appropriate.
/// Rename tmp file.
/// ...
/// Disengage unlink guard.
unlink_guard.disengage();
}
On success I use file. On failure I want this file to be missing.
This could be achived if POSIX had support for link()-ing of previously unlinked file by file descriptor, but there is no such feature :(.
So, what I am asking is for a nice, elegant solution to this kind of problems.
None exists, neither for C++ nor for other languages. You are faced with a fundamental physical reality here, not a design decision: what happens when the user pulls the plug? No programming solution can guard against that (well, there’s restore-upon-restart).
What you can do is catch POSIX signals and sometimes you can even handle them – but it’s flakey and there are tons of caveats, which another discussion on Stack Overflow details.
Most resources should not be cleared up after a segfault. If you want to do it anyway, simply collect those resources (or rather, handlers for their cleanup) in a global array, trap SIGSEGV, iterate through the cleanup routine array in the handler (hoping that the relevant memory is still intact), and perform the cleanup.
More specifically, for temporary files it helps to create them inside one of the system’s temporary folders. It’s understood that these don’t always get cleaned up by their respective applications, and either the system or the user will periodically perform cleanup instead.
Usually the solution, regardless of language or OS, is to clean up when you start the program, not (only) when you terminate. If your program can create temporary files that it cleans up on shutdown, clean up the temporary files when you start the program too.
Most everything else, like file handles, tcp connections, and so forth, is killed by the OS when your application dies.

Accesing values of another program

So, I've been wondering that how I access values of different program with my c++ code.
I understand that I have to know the memory location and access it somehow but I don't really know how.
Let's say that I have a game where I have a character that has a certain amount of health and I want to read that health with my c++ code (similar to how you can read different values with the cheat engine program).
How would I accomplish this?
For clarity: Operating system is windows
You can use the ReadProcessMemory/VirtualQuery (safer than ReadProcessMemory) and WriteProcessMemory functions.
If you are clever you can inject a DLL, then you can use pointers in your code
int * money = 0x00400000+0x00ABCDEF;//pointer to money address
*money = 5000;//set money to 5000.
if you need DLL examples, here are some:
Red Alert 3 Player Information Mod
Need for Speed: Underground 2 cheat mod
Sometimes pointers can change what they point to, this can be "dangerous" in terms of the application.
When you access a pointer which points to a protected memory area, inaccessible memory, not to the stuff you want or an invalid location your application may crash. I don't know how Cheat Engine prevents it but you have a few options, the ones I suggest:
Exit application gracefully and let the user know you couldn't handle it
Handle the problem with a try / catch block instead? (be sure to capture the correct error)
Hard exit the application
Do nothing and let the application behave weird / crash
... more and more
I also wrote pointer class myself which handles the dereferencing and stops when an error is encountered (returns null)
//null as last parameter automaticly "Dereferences"
template<class T = DWORD, class S = DWORD> struct Pointer
{
private:
std::vector<S> params;
S variable;
bool MoreThanOne;
public:
//null as last parameter automaticly "Dereferences"
template<class... Args>
Pointer(Args... args)
{
std::array<S, sizeof...(args)> list = {args...};
for( auto i : list)
params.push_back(i);
if(params.size() > 1)
MoreThanOne = true;
else
MoreThanOne = false;
}
T ResolvePointer()
{
variable = params[0];
if(!MoreThanOne)
return (T)variable;
try
{
auto it = params.begin();
++it;
for(; it != params.end(); ++it)
{
if(*reinterpret_cast<S*>(variable) == NULL)
return static_cast<T>(NULL);
variable = *reinterpret_cast<S*>(variable) + *it;
}
}
catch(...)
{
return static_cast<T>(NULL);
}
return (T)variable;
}
T operator()()
{
return ResolvePointer();
}
};
usage:
unsigned long ipaddr = htonl(Pointer<unsigned long>(0x00400000+0x008E3A74,0x04,0x38,NULL)());//pointer to players IP address
if(ipaddr != NULL)//....
You can't access variables in another process unless:
Your program uses "debug functions" to access the values.
You use some sort of IPC (shared memory, pipes, message queues) to share/transfer the data.
Each process has its own address space [1], and there is no way to access into another process's address space without some mechanism to access it.
[1] Assuming we're talking about a "real" OS that uses proper memory management. In some OS's such as traditional DOS, there is no memory protection between processes. But no sane person works with these OS's unless the system is running with a very feeble processor and small amounts of memory.
You should not write to another process's memory space without using specific IPC mechanisms. Operating systems typically prevent this for obvious reasons. Instead, you would need to use the target application's extension mechanisms, or decompile / modify / hex edit to effect the changes you want. That being said, doing so may be in violation of the terms of service for the software you are messing with.
To be clear, the code will compile just fine, letting you set a pointer to whatever arbitrary address you'd like, but once you try to read or write that address, the OS will step in and cause an error condition.
If you aren't violating the software's EULA by doing so, here are some pointers for finding things you might like to modify:
If the code can be decompiled into some readable source form, do so and make modifications there.
Edit the compiled binary with a hex editor, look for well-defined values and change them (does the max_health always start out at 25? That might be unique enough to locate and modify). A note about this: Make sure the values you intend to insert fit in the same space as the original values, otherwise you will break things and have undefined results.
Does the application provide an extension mechanism, such as a scripting API or mod support? If so, this can be a vector for causing the types of system changes you want.

Detect Incorrect stack variable usage

My application gives certain works to the worker agency to execute in a thread pool thread as given below
void Execute ProcessWork
{
int nRes = 0;
CFireProcessMessageWork *pProcessMessageWork = new CFireProcessMessageWork();
// Incorrect use of stack variable
pProcessMessageWork->m_pStatus = &nRes;
// Worker Agency
m_pMessageWorkerAgency->SubmitWork(pProcessMessageWork);
}
The definition of CFireProcessMessageWork is given below. The DoWork method of the class given below will be executed in a worker thread. Since the variable nRes is used in an improper way, my application crashes occasionally. I spent almost a week to identify the cause of the issue. I tried page heap with full options and Stack Frames (/RTCs) to detect the issue. But the application crashed at a location which has no relationship with the issue.
Is there any tools microsoft provides to detect these kind of issues?
class CFireProcessMessageWork
{
public:
int *m_pStatus;
public:
CFireProcessMessageWork()
{
m_pStatus = NULL;
}
int DoWork()
{
// Using Address of nRes
*mpStatus = 0;
// Do Some Work and Pass mpStatus to fill the error code
HRESULT hRes = pGEMMessageEvents->ProcessMessage(varData, m_nMsgCount, m_newTkt,m_idxFunc,&m_nRetVal);
return *mpStatus
}
}
The problem is that each one of those lines makes sense to the compiler. There is nothing wrong with them, and just the combination is not really good. Even then, it would require a good amount of extra work and analysis to determine that it is a wrong use.
Consider for example, that you could be joining the worker thread in the same function, and then everything would be correct, if the function did not process in a different thread but just manipulated the code in the SubmitWork call, then it would be correct... and the compiler does not necessarily know about threads, so the fact is that it is almost impossible for the compiler to detect this.
On the other hand, this is something that should be quite obvious to a reviewer, so it can be better tackled by reviewing code. Other possible options would be using some form of shared ownership to handle the resources --which might imply more cost:
void Execute ProcessWork {
std::shared_ptr<int> nRes = std::make_shared<int>( 0 );
CFireProcessMessageWork *pProcessMessageWork = new CFireProcessMessageWork();
pProcessMessageWork->m_pStatus = nRes; // copies the shared_ptr
m_pMessageWorkerAgency->SubmitWork(pProcessMessageWork);
}
In this case, the shared ownership of the object at the cost of an extra allocation, guarantees that the thread will not cause undefined behavior while updating the state. But while this will make the program correct from a language point of view, it might still be undesired: the status will not be readable outside of the worker thread, as the only other reference is outside of the worker control.
You are writing a syntactically valid code here by passing &nRes, however since it is a local varaible in stack and it is being accessed in some other thread, the address is not going to be valid, resulting in crash. I think a careful peer code review should help resolve such issues.

Side effects of exit() without exiting?

If my application runs out of memory, I would like to re-run it with changed parameters. I have malloc / new in various parts of the application, the sizes of which are not known in advance. I see two options:
Track all memory allocations and write a restarting procedure which deallocates all before re-running with changed parameters. (Of course, I free memory at the appropriate places if no errors occur)
Restarting the application (e.g., with WinExec() on Windows) and exiting
I am not thrilled by either solution. Did I miss an alternative maybe.
Thanks
You could embedd all the application functionality in a class. Then let it throw an expection when it runs out of memory. This exception would be catched by your application and then you could simply destroy the class, construct a new one and try again. All in one application in one run, no need for restarts. Of course this might not be so easy, depending on what your application does...
There is another option, one I have used in the past, however it requires having planned for it from the beginning, and it's not for the library-dependent programmer:
Create your own heap. It's a lot simpler to destroy a heap than to cleanup after yourself.
Doing so requires that your application is heap-aware. That means that all memory allocations have to go to that heap and not the default one. In C++ you can simply override the static new/delete operators which takes care of everything your code allocates, but you have to be VERY aware of how your libraries, even the standard library, use memory. It's not as simple as "never call a library method that allocates memory". You have to consider each library method on a case-by-case basis.
It sounds like you've already built your app and are looking for a shortcut to memory wiping. If that is the case, this will not help as you could never tack this kind of thing onto an already built application.
The wrapper-program (as proposed before) does not need to be a seperate executable. You could just fork, run your program and then test the return code of the child. This would have the additional benefit, that the operating system automatically reclaims the child's memory when it dies. (at least I think so)
Anyway, I imagined something like this (this is C, you might have to change the includes for C++):
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define OUT_OF_MEMORY 99999 /* or whatever */
int main(void)
{
int pid, status;
fork_entry:
pid = fork();
if (pid == 0) {
/* child - call the main function of your program here */
} else if (pid > 0) {
/* parent (supervisor) */
wait(&status); /* waiting for the child to terminate */
/* see if child exited normally
(i.e. by calling exit(), _exit() or by returning from main()) */
if (WIFEXITED(status)) {
/* if so, we can get the status code */
if (WEXITSTATUS(status) == OUT_OF_MEMORY) {
/* change parameters */
goto fork_entry; /* forking again */
}
}
} else {
/* fork() error */
return 1;
}
return 0;
}
This might not be the most elegant solution/workaround/hack, but it's easy to do.
A way to accomplish this:
Define an exit status, perhaps like this:
static const int OUT_OF_MEMORY=9999;
Set up a new handler and have it do this:
exit(OUT_OF_MEMORY);
Then just wrap your program with another program that detects this
exit status. When it does then it can rerun the program.
Granted this is more of a workaround than a solution...
The wrapper program I mentioned above could be something like this:
static int special_code = 9999;
int main()
{
const char* command = "whatever";
int status = system(command);
while ( status == 9999 )
{
command = ...;
status = system(command);
}
return 0;
}
That's the basicness of it. I would use std::string instead of char* in production. I'd probably also have another condition for breaking out of the while loop, some maximum number of tries perhaps.
Whatever the case, I think the fork/exec route mentioned below is pretty solid, and I'm pretty sure a solution like it could be created for Windows using spawn and its brethren.
simplicity rules: just restart your app with different parameters.
it is very hard to either track down all allocs/deallocs and clean up the memory (just forget some minor blocks inside bigger chunks [fragmentation] and you still have problems to rerun the class), or to do introduce your own heap-management (very clever people have invested years to bring nedmalloc etc to live, do not fool yourself into the illusion this is an easy task).
so:
catch "out of memory" somehow (signals, or std::bad_alloc, or whatever)
create a new process of your app:
windows: CreateProcess() (you can just exit() your program after this, which cleans up all allocated resources for you)
unix: exec() (replaces the current process completely, so it "cleans up all the memory" for you)
done.
Be warned that on Linux, by default, your program can request more memory than the system has available. (This is done for a number of reasons, e.g. avoiding memory duplication when fork()ing a program into two with identical data, when most of the data will remain untouched.) Memory pages for this data won't be reserved by the system until you try to write in every page you've allocated.
Since there's no good way to report this (since any memory write can cause your system to run out memory), your process will be terminated by the out of memory process killer, and you won't have the information or opportunity for your process to restart itself with different parameters.
You can change the default by using the setrlimit system call, to to limit the RLIMIT_RSS which limits the total amount of memory your process can request. Only after you have done this will malloc return NULL or new throw a std::bad_alloc exception when you reach the limit that you have set.
Be aware that on a heavily loaded system, other processes can still contribute to a systemwide out of memory condition that could cause your program to be killed without malloc or new raising an error, but if you manage the system well, this can be avoided.