memset suggestion.

Ben Lindstrom mouring at etoh.eviladmin.org
Sat Nov 9 04:20:47 EST 2002


On Fri, 8 Nov 2002, Andy Polyakov wrote:

> > > > Since 3.x is rolling out with -fno-builtin-<comand> support maybe we
> > > > should test for 3.x and set -fno-builtin-memset which should stop gcc from
> > > > optimizing it away.  And maybe everyone should look for the same feature
> > > > in their favorite compiler.
>
> Why not pick and stick to a workaround that works with all compilers, is
> independent on compiler flags and is safe at any optimization level? As
> pointed out in my (sorry for quoting myself:-) submission to Bugtraq
> http://online.securityfocus.com/archive/1/298835/2002-11-05/2002-11-11/0
> that is. In case you wonder "a variety of tested compilers" includes
> various versions of GCC (2.9x-3.1) on various platforms, Sun Forte for
> SPARC Solaris, Intel C for x86 Linux, DEC C for Alpha Linux, MIPSpro C
> for IRIX, HP C for PA-RISC HPUX and Microsoft compilers.
>

Until the next round of optimizators come out that are smart enough to
optimize that functional call out of existance.  Again we are left with a
hack that may or may not stand the test of time.

> > Everyone uses memset() to clear inmemory passwords so people can't go
> > digging around in /dev/kmem.  If memset() is optimizated out then the
> > password still stick around in memory until it is reallocated and reused.
>
> Well, those who can go digging around in /dev/kmem most likely can debug
> anybody else's process as well, and it would be hard to hide secrets
> from them in either case. So that this is hardly the biggest issue. The
> prime reason for memset-ting is to avoid unintentional exposure of
> secret as part of reallocated buffer in the *same* process context. E.g.
> when it gets used as padding data in an I/O buffer. Or you have some
> other reason to mistrust the rest of the code, e.g. you read a secret as
> root, do whatever that needs to be done and drop privileges making it
> possible for user to attach to process and inject code that would
> recover root secret.
>

<nod> I'm aware of that also.  However, a lot of newer system allocation
code allows for either clearing memory before passing to the application
or writing over it with new random junk.

So that would affect older systems which may or may not be fixable.

> > But this is only half of the issue.  It could still be in registers or in
> > the stack.  Which memset() does not solve. I saw a post on OpenBSD
> > mailinglist that gave an example of a function that may work for clearing
> > all three and that should not be optimized out.
>
> And you still have another potential leak you can't address even with
> this. Swap partition to be specific. I mean system swaps out page with
> secret, then you run memset and exit. The secret can be recovered by
> anybody who has physical access to the machine. So that you have lock in
> memory not only secret buffers, but relevant portion of stack as well...
>

<smile> You tell me everyone does not have encrypted swap?!  I thought it
was the norm these days.. <chuckle>

> > I don't know how much action should be taken on this. Hacking around one
> > gcc bug always leads to another version of gcc horking up a furball or
> > some other compiler whining and moaning about it.
>
> I fail to understand why are you people trying to address it as if it
> was a gcc-specific problem? It's a generic problem and we should look
> for more common solution. Well, it can't be completely system
> independent, but at least I see no reason why it has to be dependant on
> any particular compiler implementation.
>

The reason being is if for some insane reason code like this:

void *guaranteed_memset(void *v,int c,size_t n)
{ volatile char *p=v; while (n--) *p++=c; return v; }


takes off.. It may become part of libc.. And down the road you'll end up
with it being optimized out again.  The only CORRECT way of handling it is
to tell the compiler to keep it's grubby hands off memset().  There is no
other correct solution.  Everything else is just a hack waiting to fail
down the road.. If not a polution of C namespace which is horrific enough
as it.

The burn_stack() example I was looking for was posted by markus@ and it
was brough up as soon as compilers were smart enough to know about tail
end recursion it would be optimized away yet again.

Every time I see a solution based on a C hack.. I see at least one or two
people peg what compilers may be able to do in the future to optimize
code.

Thus I think this really boils down to flaws in the compiler's
optimization and there is not much hope for us to hack around it for any
long term solution.  Broken compilers *NEED* to be fixed.  If GCC,
Microsoft, Sun, etc don't understand this then we as a community need to
drill it into their heads.

- Ben




More information about the openssh-unix-dev mailing list