wmkhoo / taintgrind

A taint-tracking plugin for the Valgrind memory checking tool
GNU General Public License v2.0
249 stars 42 forks source link

Tainting string data type #41

Open misalungi opened 3 years ago

misalungi commented 3 years ago

Hi,

Is Taintgrind follows operations on std::string? In my code, the data is tainted until it is converted to the string data type. After that, taintgrind loses the flow of the data!

wmkhoo commented 3 years ago

Thanks for bringing up this issue. Could you provide a test case that demonstrates the issue?

misalungi commented 3 years ago

Here I have two modules. The first one produces a random data (ebBalance). The second module sends reading request in TLM to the first one to read ebBalance. Immediately after data conversion to string, the taint flow will be lost.

in energyBalance module:

` { ... ebBalance= rand()%2000-1000;

                        TNT_TAINT(&ebBalance, sizeof(ebBalance));
                         std::cout<< " data for tainting is: " << ebBalance << std::endl;

} // balanceGenerator()

void energyBalance::b_transport(int id, tlm::tlm_generic_payload& tlmPayload, sc_core::sc_time& delay) { if(tlmPayload.get_command() == tlm::TLM_READ_COMMAND) { if (tlmPayload.get_address() == 0x10 ) {

            tlmPayload.set_data_ptr((unsigned char*)ebBalance);
            tlmPayload.set_response_status(tlm::TLM_OK_RESPONSE); }

} }

`

in second mudole:

` { ... if(tlmPayload.get_response_status() == tlm::TLM_OK_RESPONSE) {

         int reveivedEB= (int)(tlmPayload.get_data_ptr());

         sEBalance= std::to_string(reveivedEB);                             // data after here is not tainted

                    std::string temp = sEBalance;                         // I made this one for testing. temp is not tainted

`

misalungi commented 3 years ago

Another issue is that when I get string data to the TNT_TAINT(&a, sizeof(a)) or to TNT_IS_TAINTED(t, &a, sizeof(a)) it raises an error. So I have to first convert the data to int, then pass it to TNT_IS_TAINTED(t, &a, sizeof(a))!

misalungi commented 3 years ago

I think the problem is not about tainting string data type, it is about the size of tainted data which will be changed after converting to string. In piece of code which I mentioned above, in second module sEBalance is tainted, but the propagation of sEBalance is not followed in the rest of program. To check if Taintgrind can follow the propagation of string data type, instead of tainting ebBalance in module 1, I passed sEBalance to the TNT_TAINT function. It followed the propagation of sEBalance through the rest of program. The size of ebBalance which is a integer is 4 and the size of sEBalance is 32.

wmkhoo commented 3 years ago

At least for me, std::to_string is implemented by _itoa.c.

const char _itoa_upper_digits[36]
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
...
const char *digits = (upper_case? _itoa_upper_digits : _itoa_lower_digits);
...
*--buflim = digits[value % Base];

In the above, value, which is tainted, is used as an index to copy the corresponding characters into buflim. The taint will not be propagated, because pointer tainting is not implemented (see Pointer tainting).

So, yes. sEBalance will not be tainted after std::to_string. The only way is to taint it manually after std::to_string. Thanks for raising this issue.