This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] [PATCH] Support explicit_bzero, memset_s, memzero_explicit, or similar.


(sorry; sent this before, but from the wrong address.)

On Mon, Dec 15, 2014 at 12:35 PM, Rich Felker <dalias@libc.org> wrote:

Thanks for the reply, Rich!

>> Different operating systems, libraries, and standards have
>> approached this problem differently.  Windows provides
>>       SecureZeroMemory(void *, size_t);
>> The BSD family is moving towards
>>       explicit_bzero(void *, size_t);
>> And the C11 standard defines
>>       memset_s(void *, rsize_t, int, size_t);
>> And OpenSSL (along with LibreSSL and BoringSSL) provide:
>>       OPENSSL_cleanse(void *, size_t);
>> And in the Linux kernel these says, they're using:
>>       memzero_explicit(void *, size_t);
>
> None of these solve the problem, because the compiler is free to have
> copied part of all of this buffer into other temporary storage on the
> stack or registers. This is especially the case if SIMD optimizations
> are used. Solving the problem (which isn't really even a problem, just
> a hardening consideration) correctly requires compiler features.

I agree that a *complete* solution would require compiler features.
But nonetheless, a non-removable memset() equivalent is useful for
some hardening.  At  the very least, we could make sure that the
documentation explains this point.

It's not clear to me from your response, whether you think including
an explicit_bzero() or a memset_s() implementation is "worse than
nothing" because of the register and spilling issue, or whether you
think it would be worth providing anyway with appropriate caveats?

 [...]
>> Now, at first glance it would seem that that memset_s() is the
>> obvious choice, since it's the one supported by a standard.  But
>> it's a part of a much larger pile of bounds-checking variants of
>> other C functions (C11 Annex K).  It's *possible* to
>> implement memset_s() without the rest of Annex K, but it requires a
>> bit of infrastructure to be fully compliant.  (Like, we would need
>> an rsize_t, and a set_constraint_handler_s().  I do not believe we
>> would need a full implementation of Annex K.)
>
> errno_t is defined (by Annex K) as int and rsize_t is defined as
> size_t, so we could just omit these types entirely and use the
> standard types (int and size_t) and still not conflict with the Annex
> K definition. There's no reason to use or even provide the ugly and
> useless MS/Annex K typedefs.

Attached is an approximate (probably buggy, I am new to glibc)
implementation of the memset_s variant. I dedicate it (and this email)
to the public domain.

yrs,
-- 
Nick

Attachment: memset_s.patch
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]