Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How-to ensure that compiler optimizations don't introduce a security risk?

I have to write a Windows service that handles at some point confidential data (such as PIN codes, passwords, and so on). Those informations are needed for a very short amount of time: usually they are sent almost immediately to a smart card reader.

Lets consider this piece of code:

{   std::string password = getPassword(); // Get the password from the user    writePasswordToSmartCard(password);    // Okay, here we don't need password anymore.   // We set it all to '\0' so it doesn't stay in memory.   std::fill(password.begin(), password.end(), '\0'); } 

Now my concern is about compiler optimizations. Here the compiler might detect that password is about to be deleted and that changing its value at this point is useless and just remove the call.

I don't expect my compiler to care about the value of future-unreferenced memory.

Are my concerns legitimate ? How can I be sure that such a piece of code won't be optimized-out ?

like image 502
ereOn Avatar asked Sep 24 '10 08:09

ereOn


People also ask

How do I stop compiler optimization?

Use the command-line option -O0 (-[capital o][zero]) to disable optimization, and -S to get assembly file. Look here to see more gcc command-line options.

How are the compiler optimization techniques?

There are several techniques for optimizing compilers. The three main areas of source-code tuning are as follows: Programming techniques that take advantage of the optimizing compilers and the system architecture. BLAS, a library of Basic Linear Algebra Subroutines.

What do compiler optimizations do?

In computing, an optimizing compiler is a compiler that tries to minimize or maximize some attributes of an executable computer program. Common requirements are to minimize a program's execution time, memory footprint, storage size, and power consumption (the last three being popular for portable computers).


2 Answers

Yes, your concerns are legitimate. You need to use specifically designed function like SecureZeroMemory() to prevent optimizations from modifying your code behavior.

Don't forget that the string class should have been specifically designed for handling passwords. For example, if the class reallocates the buffer to hold a longer string it has to erase the buffer before retunring it to the memory allocator. I'm not sure, but it's likely std::string doesn't do that (at least by default). Using an unsuitable string handling class makes all your concerns worthless - you'll have the password copied all over the program memory befoe you even know.

like image 81
sharptooth Avatar answered Oct 02 '22 22:10

sharptooth


It's problematic, but for another reason. Who said that std::string password = getPassword(); doesn't leave yet another copy in the memory? (Probably you need to write a "secure" allocator class for this that zeros memory on "destruct" or "deallocate")

In your peace of code you can avoid optimization by getting a volatile pointer to the string data (I don't know if you can do it in standard way) and then zero the data through.

like image 44
Yakov Galka Avatar answered Oct 02 '22 22:10

Yakov Galka