RE: When scrubbing secrets in memory doesn't work

From: Michael Wojcik (Michael.Wojcikat_private)
Date: Tue Nov 12 2002 - 08:07:20 PST

  • Next message: Ed Reed: "NOVL-2002-2963827 - Remote Manager Security Issue - NW5.1"

    Reposted.
    
    > -----Original Message-----
    > From: Michael Wojcik 
    > Sent: Wednesday, November 06, 2002 12:25 AM
    > To: 'Michael Howard'
    > Cc: bugtraqat_private
    > Subject: RE: When scrubbing secrets in memory doesn't work
    > 
    > 
    > > From: Michael Howard [mailto:mikehowat_private]
    > > 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
    > 
    



    This archive was generated by hypermail 2b30 : Tue Nov 12 2002 - 16:21:13 PST