Zapping memory and C++ compatibility

Mike Patnode mike.patnode at centrify.com
Mon Nov 23 11:30:32 EST 2009


Without a reference in front of me, I'm fairly certain C style casts are
mapped to reinterpret_cast in C++.  In this case it's simple syntax
sugar.  In any case, they are certainly allowed in C++.

mp

-----Original Message-----
From: krbdev-bounces at mit.edu [mailto:krbdev-bounces at mit.edu] On Behalf
Of Derek Atkins
Sent: Saturday, November 21, 2009 4:51 AM
To: ghudson at mit.edu
Cc: krbdev at mit.edu
Subject: Re: Zapping memory and C++ compatibility

I think the problem is that you cannot use a C-style cast to cast an
object to a void* pointer in C++.  You might need to use a 'static_cast'
to do so, which means you might need to do something like:

#ifdef __cplusplus
#define krb5int_zap_data(ptr, len) memset(static_cast<volatile void 
*>(ptr), 0,
len)
#else
#define krb5int_zap_data(ptr, len) memset((volatile void *)ptr, 0, len)
#endif

-derek

Quoting ghudson at MIT.EDU:

> Back in 2002 or so, people noticed that certain compilers (I think gcc
> 3.x and Visual C++) would sometimes optimize out a memset() which they
> could prove doesn't affect the execution of the program according to
> standardized behaviors (which doesn't include accessing stack garbage
> or the contents of core dumps or anything of that sort).  So, there
> was a lot of discussion about how to securely zero passwords or
> cryptographic keys.
>
> We had out own discussion, which you can review at
> http://mailman.mit.edu/pipermail/krbdev/2002-November/000871.html.
> The eventual upshot was this collection of macros or inlines:
>
> Win32: #define krb5int_zap_data(ptr, len) SecureZeroMemory(ptr, len)
> gcc:   static inline void krb5int_zap_data(void *ptr, size_t len) {
>       memset(ptr, 0, len); asm volatile ("" : : "g" (ptr), "g" (len));
}
> else:  #define krb5int_zap_data(ptr, len) memset((volatile void 
> *)ptr, 0, len)
>
> The last construction was based on the idea that a hypothetical
> compiler might see the cast through volatile void * and decide not to
> perform an optimization.  It's not clear to me how valid this
> reasoning is, since neither the proximal type (after the implicit cast
> to void * by the call to memset) nor the original type is volatile.
>
> Today's problem is that the last construction isn't valid C++.  We
> have a test case which tries passing k5-int.h through C++ compiler,
> and it now fails on Solaris with the native compiler.  It didn't fail
> before because the macro was never expanded within k5-int.h, but now
> it gets expanded by the new zapfree() inline function.
>
> So, I'm trying to figure out how to resolve this C++ compatibility
> issue without raising the likelihood of an information leakage
> vulnerability.  A possible choice is to make the macro more obviously
> wishy-washy by explicitly casting ptr back to void *:
>
>  memset((void *)(volatile void *)ptr, 0, len)
>
> Anyway, advice appreciated if anyone on the list has expertise in this
> issue.
> _______________________________________________
> krbdev mailing list             krbdev at mit.edu
> https://mailman.mit.edu/mailman/listinfo/krbdev
>



-- 
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       warlord at MIT.EDU                        PGP key available

_______________________________________________
krbdev mailing list             krbdev at mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev




More information about the krbdev mailing list