Reposted. > -----Original Message----- > From: Michael Wojcik > Sent: Wednesday, November 06, 2002 12:25 AM > To: 'Michael Howard' > Cc: bugtraq@securityfocus.com > Subject: RE: When scrubbing secrets in memory doesn't work > > > > From: Michael Howard [mailto:mikehow@microsoft.com] > > Sent: Tuesday, November 05, 2002 5:13 PM > > > [memset doesn't always] > > I don't know if you followed the discussion on Vuln-dev after > Peter Gutmann mentioned your article, 30-31 October, but Dom > De Vitto[1] and I both described ways of avoiding this > problem that work on any conforming C90/94/99 > implementation[2]. Pavel Kankovsky[3] and I both noted that > De Vitto's simple suggestion of using the "volatile" > sc-specifier should sufficient for any conforming C > implementation, at least as we read the standards (and with > the caveat that passing a volatile-qualified pointer to > memset may not be valid, so assignment might have to be done > manually), though I prefer the "external memset" approach for > various reasons[4]. Dan Kaminsky makes the general point > that introducing dependencies that can only be evaluated at > run time also does the trick[5], though that's generally more > work than the simple "volatile" and "external memset" solutions. > > In sum, this is not a particularly interesting problem. It's > useful to have it pointed out (and we might have hoped that > the authors of security-sensitive software would be more > familiar with optimization techniques, the language > standards, and what might happen to this kind of application > of memset), and the maintainers of code that handles > passwords should check for and correct it, but contra Peter > Gutmann it does not appear to be a hard problem to solve, nor > need solutions be necessarily implementation-specific. > > Of the solutions given in your article, all should work on > your implementation, but the first: > > memset(ptr, 0, len); > (volatile char *)ptr[0] = (volatile char *)ptr[1]; > > is clearly preferable as it is portable. (I think - that > lvalue cast may not be legal, actually. Or, for that matter, > casting on volatility. I'd have to check.) > > It's worth noting that I believe the standard *still* allows > a conforming implementation to skip the memset in the case of > your first solution, too. Because the pointer being passed > to memset is not itself volatile-qualified, the > implementation can apply the "as if" rule - the generated > code need only behave *as if* following the rules of the > abstract machine, provided all side effects visible to the > program are maintained. (That's a gloss, not language taken > directly from the standard, but it's the basic idea.) A > clever optimiser could note that it is only necessary that it > perform the volatile read and write in the second line. > > So that's not a portable solution either, actually. My > advice: use an external memset wrapper. Simple, safe, portable. > > 1. http://makeashorterlink.com/?A5C922B52 > 2. http://makeashorterlink.com/?E50A12B52 > 3. http://makeashorterlink.com/?J11A62B52 > 4. http://makeashorterlink.com/?H32A23B52 > 5. http://makeashorterlink.com/?T1A924B52 > > Michael Wojcik > Principal Software Systems Developer, Micro Focus >