4 ms·
When I allocate the key on the heap, the memset is carried (heavily optimized and inlined). When I allocate key on the stack, it disappears. Using gcc -03:
by smegel 12y ago
When I allocate the key on the heap, the memset is carried (heavily optimized and inlined). When I allocate key on the stack, it disappears. Using gcc -03:
#include <string.h>
void doSecure(void)
{
/*char key[32];*/
char *key = (char*) malloc(sizeof(char)*32);
memset(key,sizeof(char),32);
}
int main(void)
{
doSecure();
return 0;
}
-- key on stack
main:
.LFB13:
.cfi_startproc
xorl %eax, %eax
ret
.cfi_endproc
-- key on heap
main:
.LFB13:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $32, %edi
call malloc
movabsq $72340172838076673, %rdx
movq %rdx, (%rax)
movq %rdx, 8(%rax)
movq %rdx, 16(%rax)
movq %rdx, 24(%rax)
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
- rwg 12y agoThat's not a behavior you can count on — clang 3.4 will optimize doSecure() down to "ret" and main() down to "xorl %eax, %eax" + "ret" in both cases, for example. Also, gcc not optimizing out the malloc + memset in the heap case seems like a missed optimization that the gcc devs might fix in the future.
- tedunangst 12y agoA more realistic idiom is memset followed by free. The free provides a solid hint to the compiler that the object is dead without relying on escape analysis.
- smegel 12y agoNaturally, however adding free made no difference in this case. I guess if your dealing with a raw pointer rather than an array type, gcc cant be sure what memory you intend to erase.
- pjmlp 12y agoThat is compiler specific behaviour. You have zero guarantees it will work in another compiler or even between releases of the same one. Never take a compiler behaviour for the standard. That's the beauty of standards.
- wolf550e 12y agomemset(key,sizeof(char),32); Note that you are not clearing 32 bytes with NUL (byte value 0). You are clearing 32 bytes with byte value 1 == (int)(sizeof(char). That's why memset that works 8 bytes at a time fills memory with 72340172838076673 == 0x0101010101010101 http://linux.die.net/man/3/memset http://linux.die.net/man/3/memset