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