Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it not possible to make a C++ application "Crash Proof"?

Let's say we have an SDK in C++ that accepts some binary data (like a picture) and does something. Is it not possible to make this SDK "crash-proof"? By crash I primarily mean forceful termination by the OS upon memory access violation, due to invalid input passed by the user (like an abnormally short junk data).

I have no experience with C++, but when I googled, I found several means that sounded like a solution (use a vector instead of an array, configure the compiler so that automatic bounds check is performed, etc.).

When I presented this to the developer, he said it is still not possible.. Not that I don't believe him, but if so, how is language like Java handling this? I thought the JVM performs everytime a bounds check. If so, why can't one do the same thing in C++ manually?

UPDATE
By "Crash proof" I don't mean that the application does not terminate. I mean it should not abruptly terminate without information of what happened (I mean it will dump core etc., but is it not possible to display a message like "Argument x was not valid" etc.?)

like image 984
Enno Shioji Avatar asked Dec 23 '10 05:12

Enno Shioji


4 Answers

You can check the bounds of an array in C++, std::vector::at does this automatically.

This doesn't make your app crash proof, you are still allowed to deliberately shoot yourself in the foot but nothing in C++ forces you to pull the trigger.

like image 117
Martin Beckett Avatar answered Nov 09 '22 06:11

Martin Beckett


No. Even assuming your code is bug free. For one, I have looked at many a crash reports automatically submitted and I can assure you that the quality of the hardware out there is much bellow what most developers expect. Bit flips are all too common on commodity machines and cause random AVs. And, even if you are prepared to handle access violations, there are certain exceptions that the OS has no choice but to terminate the process, for example failure to commit a stack guard page.

like image 20
Remus Rusanu Avatar answered Nov 09 '22 05:11

Remus Rusanu


By crash I primarily mean forceful termination by the OS upon memory access violation, due to invalid input passed by the user (like an abnormally short junk data).

This is what usually happens. If you access some invalid memory usually OS aborts your program.

However the question what is invalid memory... You may freely fill with garbage all the memory in heap and stack and this is valid from OS point of view, it would not be valid from your point of view as you created garbage.

Basically - you need to check the input data carefully and relay on this. No OS would do this for you.

If you check your input data carefully you would likely to manage the data ok.

like image 4
Artyom Avatar answered Nov 09 '22 07:11

Artyom


I primarily mean forceful termination by the OS upon memory access violation, due to invalid input passed by the user

Not sure who "the user" is.

You can write programs that won't crash due to invalid end-user input. On some systems, you can be forcefully terminated due to using too much memory (or because some other program is using too much memory). And as Remus says, there is no language which can fully protect you against hardware failures. But those things depend on factors other than the bytes of data provided by the user.

What you can't easily do in C++ is prove that your program won't crash due to invalid input, or go wrong in even worse ways, creating serious security flaws. So sometimes[*] you think that your code is safe against any input, but it turns out not to be. Your developer might mean this.

If your code is a function that takes for example a pointer to the image data, then there's nothing to stop the caller passing you some invalid pointer value:

char *image_data = malloc(1);
free(image_data);
image_processing_function(image_data);

So the function on its own can't be "crash-proof", it requires that the rest of the program doesn't do anything to make it crash. Your developer also might mean this, so perhaps you should ask him to clarify.

Java deals with this specific issue by making it impossible to create an invalid reference - you don't get to manually free memory in Java, so in particular you can't retain a reference to it after doing so. It deals with a lot of other specific issues in other ways, so that the situations which are "undefined behavior" in C++, and might well cause a crash, will do something different in Java (probably throw an exception).

[*] let's face it: in practice, in large software projects, "often".

like image 3
Steve Jessop Avatar answered Nov 09 '22 06:11

Steve Jessop