My software has crashed and generated a core file.
After investigating the core file, crash has occurred when free() call has been made.
Noticed that the address that was passed to free was invalid.
#1 0x000055ea2d52f630 in __free [__be___free] (ptr=0x7f8bd51a63ef, saved_caller_pc=0x55ea29cceb76 <abc+998>, attr=0x0)
The address 0x7f8bd51a63ef is invalid.
Given that we are running the program on a x86_64 ISA the word length would be 8 bits and the memory address of the word would either end with 0 or 8. Since in our case, it is ending with f, it made me to suspect it to be an invalid address. I confirmed this by dumping the memory around the memory location 0x7f8bd51a63ef (using the command x) and inspected the header data of the memory block corresponding to the address 0x7f8bd51a63ef - they appeared to be shifted by 1 byte (the shift was evident from the magic number in the header).
So I dumped the data the memory around the memory location 0x7f8bd51a63f0 (which is 1 bytes higher than the previous memory address), now all the header data was displayed properly.
Additional Info: And from the memory header data, I could see that it was not an already free'd memory block
My code looks like -
100 static void
101 func (<struct type1> *arg1, <struct type2> **arg2)
102 {
103 <struct type2> *var;
104 var = *arg2;
...
...
...
...
...
125 my_free(var->abc.xyz);
...
...
130
}
Structure type2 would look like -
struct type3 {
...
void * xyz; ---> Pointer to a timer related object
...
}
struct type2 {
...
type3 abc;
...
}
I inspected the code to see if anywhere in the code, we would typecast var->abc.xyz to char or uchar and decrement it. But there is no statement in the code which is doing it. There is very few access to var->abc.xyz in code -
- initializing - timer object will be malloc'ed and assigned to
var->abc.xyz - destroying - free'ing
var->abc.xyz - timer actions - since
var->abc.xyzis a timer object, we just start, stop and check whether it is running or not.
Only other thing I could suspect is a memory corruption by the previous memory block owner of type2 structure instance using the dangling pointer.
Previous memory block owner means - a thread, "Thread A", which had previously got the memory block, "Block M", when it called malloc and later free'd. However, "Thread A" still has a pointer holding the memory address for the memory block, "Block M". Now when thread "Thread B" makes a request through malloc, it will be allocated memory block, "Block M". Since "Thread A" still has access to "Block M", it can illegally write on "Block M"
So type2 structure instance var could be manipulated to corrupt the data at var->abc.xyz by some other thread.
- Is there a way to confirm this?
- What other possibility could be there?
Please note: I have also checked for possibility of memory overrun by previous memory block (previous memory block is different than previous owner of the memory block). From the memory block assigned to var, I have traced down the previous memory block and allocator of that block and checked for possibility of memory overrun through code inspection - there is no issue here as well since the previous memory block is accessed through only snprintf and the size passed to snprint is properly the limiting the access with its allocated memory.