This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [RFC] [PATCH] Support explicit_bzero, memset_s, memzero_explicit, or similar.
- From: Rich Felker <dalias at libc dot org>
- To: Richard Henderson <rth at twiddle dot net>
- Cc: Nick Mathewson <nickm at torproject dot org>, libc-alpha at sourceware dot org
- Date: Tue, 16 Dec 2014 13:01:26 -0500
- Subject: Re: [RFC] [PATCH] Support explicit_bzero, memset_s, memzero_explicit, or similar.
- Authentication-results: sourceware.org; auth=none
- References: <CAKDKvuzWYf3GcXYs4ED8XLyy58nzmvxRV84xwsKKZjPpVSFQug at mail dot gmail dot com> <20141215173527 dot GJ4574 at brightrain dot aerifal dot cx> <CAKDKvuyhgr4CmkkD+0LzSNqRUW=gUhpERoknAT3e3H7ooqpaDw at mail dot gmail dot com> <20141216052617 dot GL4574 at brightrain dot aerifal dot cx> <54905CB1 dot 3070000 at twiddle dot net>
On Tue, Dec 16, 2014 at 10:24:17AM -0600, Richard Henderson wrote:
> On 12/15/2014 11:26 PM, Rich Felker wrote:
> > I don't think the implementation as written is valid -- at least, not
> > if you allow LTO. The compiler barrier does not prevent the memset
> > from being optimized out unless the address of the buffer being memset
> > has been leaked to code the compiler cannot see. As long as it sees
> > that the asm has no way of observing the output of the memset, it can
> > optimize out the memset. Simply making the memset buffer visible to
> > the asm by passing its address (or better yet, it as a memory object)
> > in an asm constraint would probably fix this, but I'd like to have
> > someone from the GCC side confirm this.
>
> I believe a simple memory clobber (without even passing the buffer address)
> should be sufficient. The memory clobber is a very large hammer, indicating
> that *all* memory is both read and written. Thus the memset cannot be dead,
> because its results may be read by the asm.
But in the case of a function like:
int foo = 42;
memset(&foo, 0, sizeof foo);
__asm__ __volatile__ ( "" : : : "memory" );
after analysis based on compiler knowledge of the memset function, the
object foo is not "memory" because its address has never leaked. Since
the asm cannot see it, it can be optimized out to never exist at all
independently of handling the asm. If this weren't the case, presence
of asm with memory clobbers anywhere in the whole program would
prevent the compiler from optimizing out objects like this anywhere in
the whole program, which is obviously not correct.
Note that you can easily get code just like the above when memcpy_s is
inlined via LTO. I disagree with OndÅej's approach of just assuming
LTO won't happen (dynamic linking) or intentionally suppressing it.
The code should just be written with semantically correct compiler
barriers so it doesn't matter and so we're not assuming external calls
provide the needed compiler barriers.
Rich
- References:
- [RFC] [PATCH] Support explicit_bzero, memset_s, memzero_explicit, or similar.
- Re: [RFC] [PATCH] Support explicit_bzero, memset_s, memzero_explicit, or similar.
- Re: [RFC] [PATCH] Support explicit_bzero, memset_s, memzero_explicit, or similar.
- Re: [RFC] [PATCH] Support explicit_bzero, memset_s, memzero_explicit, or similar.
- Re: [RFC] [PATCH] Support explicit_bzero, memset_s, memzero_explicit, or similar.