Darren Tucker
2002-Nov-07 22:34 UTC
From RISKS: secret scrubbing code removed by optimizers
This showed up in RISKS and no one has mentioned it here yet, so.. OpenSSH contains lots of code like: char *password = read_passphrase(prompt, 0); [do stuff] memset(password, 0, strlen(password));
Ben Lindstrom
2002-Nov-07 22:41 UTC
From RISKS: secret scrubbing code removed by optimizers
I know there has been a lot of talk on private OpenBSD lists and it is being ensured that gcc never removes memset() entries on OpenBSD. Personally I think if gcc is optimizing it away it is incorrect. I believe 3.2+ GCC series supports a flag to leave memsets, but I'm not sure how usaged 3.2 is. - Ben On Fri, 8 Nov 2002, Darren Tucker wrote:> This showed up in RISKS and no one has mentioned it here yet, so.. > > OpenSSH contains lots of code like: > > char *password = read_passphrase(prompt, 0); > [do stuff] > memset(password, 0, strlen(password)); > > >From http://online.securityfocus.com/archive/82/297827 > > "clearing sensitive information such as encryption keys from memory may > not work as expected because an optimising compiler removes the memset() > if it decides it's redundant." > > "When compiled with any level of optimisation using gcc, the key > clearing call goes away because of dead code elimination." > > -- > Darren Tucker (dtucker at zip.com.au) > GPG Fingerprint D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69 > Good judgement comes with experience. Unfortunately, the experience > usually comes from bad judgement. > _______________________________________________ > openssh-unix-dev at mindrot.org mailing list > http://www.mindrot.org/mailman/listinfo/openssh-unix-dev >
Gert Doering
2002-Nov-07 23:08 UTC
From RISKS: secret scrubbing code removed by optimizers
Hi, On Fri, Nov 08, 2002 at 09:34:59AM +1100, Darren Tucker wrote:> This showed up in RISKS and no one has mentioned it here yet, so.. > > OpenSSH contains lots of code like: > > char *password = read_passphrase(prompt, 0); > [do stuff] > memset(password, 0, strlen(password)); > > >From http://online.securityfocus.com/archive/82/297827 > > "clearing sensitive information such as encryption keys from memory may > not work as expected because an optimising compiler removes the memset() > if it decides it's redundant." > > "When compiled with any level of optimisation using gcc, the key > clearing call goes away because of dead code elimination."I don't think this applies here. The compiler can't know that the memory area isn't used by other functions. What you are referring to is: int foo() { char password[100] = "secret!"; memset(password, 0, sizeof(password); return; } in that case, "password" is a local variable to the function, and the compiler can rightfully assume that it will never be accessed after function return (because it's on the stack and its scope doesn't exist anymore). gert -- USENET is *not* the non-clickable part of WWW! //www.muc.de/~gert/ Gert Doering - Munich, Germany gert at greenie.muc.de fax: +49-89-35655025 gert.doering at physik.tu-muenchen.de
Gary E. Miller
2002-Nov-08 06:08 UTC
From RISKS: secret scrubbing code removed by optimizers
Yo All! On Fri, 8 Nov 2002, Darren Tucker wrote:> Dan Kaminsky wrote: > > Has somebody actually verified this optimizing behavior in any build > > of GCC? Does voliatile actually stop it? > > Yes (gcc-3.2 on a SPARC). Yes.Same test on gcc 3.2 and gcc 2.95.2 with i686-linux. I can not get memset() to optimize away. Maybe with other switches it will. Normal compile, gcc 3.2: gcc -S testfunc.c myfunc1: pushl %ebp movl %esp, %ebp subl $136, %esp movl $.LC0, (%esp) leal -120(%ebp), %eax movl %eax, 4(%esp) call scanf leal -120(%ebp), %eax movl %eax, (%esp) movl $0, 4(%esp) movl $100, 8(%esp) call memset leave ret gcc -S -O1 testfunc.c myfunc1: pushl %ebp movl %esp, %ebp subl $136, %esp movl %edi, -4(%ebp) movl $.LC0, (%esp) leal -120(%ebp), %edi movl %edi, 4(%esp) call scanf cld movl $25, %ecx movl $0, %eax rep stosl movl -4(%ebp), %edi movl %ebp, %esp popl %ebp ret gcc -S -O2 testfunc.c and gcc -S -O3 testfunc.c myfunc1: pushl %ebp movl %esp, %ebp subl $136, %esp movl %edi, -4(%ebp) leal -120(%ebp), %edi movl %edi, 4(%esp) movl $.LC0, (%esp) call scanf xorl %eax, %eax movl $25, %ecx cld rep stosl movl -4(%ebp), %edi movl %ebp, %esp popl %ebp ret Similar results w/ gcc 2.95.3 RGDS GARY --------------------------------------------------------------------------- Gary E. Miller Rellim 20340 Empire Blvd, Suite E-3, Bend, OR 97701 gem at rellim.com Tel:+1(541)382-8588 Fax: +1(541)382-8676
Markus Friedl
2002-Nov-08 08:51 UTC
From RISKS: secret scrubbing code removed by optimizers
On Fri, Nov 08, 2002 at 09:34:59AM +1100, Darren Tucker wrote:> This showed up in RISKS and no one has mentioned it here yet, so.. > > OpenSSH contains lots of code like: > > char *password = read_passphrase(prompt, 0); > [do stuff] > memset(password, 0, strlen(password));this is not a problem, because 'password' is not on the stack. however, there are other cases when memset() is called for automatic variables. -m
Ben Lindstrom
2002-Nov-08 13:55 UTC
From RISKS: secret scrubbing code removed by optimizers
On Fri, 8 Nov 2002, Darren Tucker wrote:> Dan Kaminsky wrote: > > Has somebody actually verified this optimizing behavior in any build > > of GCC? Does voliatile actually stop it? > > Yes (gcc-3.2 on a SPARC). Yes. >does setting -fno-builtin-memset at compile time stop gcc from miscompiling? - Ben> -Daz. > > Test function: > void myfunc1() > { > char p[100]; > > scanf("%s\n", &p); > memset(p, 0, 100); > } > > gcc -s testfunc.c gives: > myfunc1: > !#PROLOGUE# 0 > save %sp, -216, %sp > !#PROLOGUE# 1 > add %fp, -120, %o1 > sethi %hi(.LLC0), %o0 > or %o0, %lo(.LLC0), %o0 > call scanf, 0 > nop > add %fp, -120, %o0 > mov 0, %o1 > mov 100, %o2 > call memset, 0 > nop > nop > ret > restore > > gcc -s -O3 testfunc.c > myfunc1: > !#PROLOGUE# 0 > save %sp, -216, %sp > !#PROLOGUE# 1 > sethi %hi(.LLC0), %g1 > or %g1, %lo(.LLC0), %o0 > call scanf, 0 > add %fp, -120, %o1 > nop > ret > restore > > Add "volatile" and inlines and unrolls memset: > myfunc1: > !#PROLOGUE# 0 > save %sp, -216, %sp > !#PROLOGUE# 1 > sethi %hi(.LLC0), %g1 > or %g1, %lo(.LLC0), %o0 > call scanf, 0 > add %fp, -120, %o1 > mov 0, %o2 > mov 0, %o3 > std %o2, [%fp-120] > std %o2, [%fp-112] > std %o2, [%fp-104] > std %o2, [%fp-96] > std %o2, [%fp-88] > std %o2, [%fp-80] > std %o2, [%fp-72] > std %o2, [%fp-64] > std %o2, [%fp-56] > std %o2, [%fp-48] > std %o2, [%fp-40] > std %o2, [%fp-32] > st %g0, [%fp-24] > nop > ret > restore > > -- > Darren Tucker (dtucker at zip.com.au) > GPG Fingerprint D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69 > Good judgement comes with experience. Unfortunately, the experience > usually comes from bad judgement. > _______________________________________________ > openssh-unix-dev at mindrot.org mailing list > http://www.mindrot.org/mailman/listinfo/openssh-unix-dev >
Seemingly Similar Threads
- [LLVMdev] Efficient Pattern matching in Instruction Combine
- [LLVMdev] Efficient Pattern matching in Instruction Combine
- [LLVMdev] Efficient Pattern matching in Instruction Combine
- question on "optim"
- [LLVMdev] striping of stdio information in llvm-gcc and clang