Page 1 of 1

memset_s

Posted: Wed Dec 28, 2016 7:56 am
by matt11235
C11 introduces memset_s, memcpy_s etc...
What do I need to do differently in the implementation to make sure that calls to these aren't optimized away? Can I just call my existing memset and let the compiler handle everything?

Re: memset_s

Posted: Wed Dec 28, 2016 8:08 am
by Love4Boobies
Your question is missing a lot of context:
  • What compiler are you using?
  • What is the implementation you are talking about of, a standard library or is it just user code that calls these functions?
  • Why are you worried about the compiler optimizing these calls away? In which way is this hurting you?

Re: memset_s

Posted: Wed Dec 28, 2016 8:10 am
by matt11235
Love4Boobies wrote:Your question is missing a lot of context:
  • What compiler are you using?
  • What is the implementation you are talking about of, a standard library or is it just user code that calls these functions?
  • Why are you worried about the compiler optimizing these calls away? In which way is this hurting you?
Sorry. I'm using GCC and this is the libc in my kernel. I wanted to implement these methods because of security reasons.

Re: memset_s

Posted: Wed Dec 28, 2016 8:28 am
by Love4Boobies
So I guess you aren't worried about these calls being optimized away, you are worried that GCC will use its built-in implementations instead of your own. (Personally, I'm not even convinced that is something you should be afraid of.) The answer is the same for memset_s as it is for memset. The option you are looking for is -fno-builtin, which is implied by -ffreestanding, which you should already be using.

Re: memset_s

Posted: Wed Dec 28, 2016 9:23 am
by matt11235
Love4Boobies wrote:So I guess you aren't worried about these calls being optimized away, you are worried that GCC will use its built-in implementations instead of your own. (Personally, I'm not even convinced that is something you should be afraid of.) The answer is the same for memset_s as it is for memset. The option you are looking for is -fno-builtin, which is implied by -ffreestanding, which you should already be using.
Sorry again, I think you're right :oops:
I did some testing and it seems that even at -O3 it doesn't throw away my calls to memset.

Re: memset_s

Posted: Wed Dec 28, 2016 9:29 am
by Kevin
If you want to be absolutely sure, let memset() call memset_s() instead of the other way round. The compiler might optimise away a memset(), but never a memset_s(). That's what you'll probably need to do in userspace where you don't use -ffreestanding.

Re: memset_s

Posted: Fri Dec 30, 2016 5:29 am
by dchapiesky
Just to clarify....

The problem is known as dead store removal and owasp has a page on it...

https://www.owasp.org/index.php/Insecur ... timization

The problem has been known for years.... like at least since 2004...

http://www.open-std.org/jtc1/sc22/wg14/ ... /n1381.pdf

Here is a GPL licensed version of the function you asked about:

https://github.com/matrixssl/matrixssl/ ... memset_s.c

Alternately if you want to develop your own you can look at:

http://www.daemonology.net/blog/2014-09 ... uffer.html

While your test did not optimize the memset away with -O3, you are not guaranteed that it won't be when combined with more code - think link time optimizations, global optimizations, etc...

From a security and code review standpoint (since you mentioned security was a primary factor), have a full set of the *_s functions is better than hoping gcc gets it right.

You might also look at Frama-C as an adjunct to proving certain functions maintain their properties.

Re: memset_s

Posted: Fri Dec 30, 2016 5:39 am
by dchapiesky
Slightly off topic but the thread did start with a mention of security concerns...

If you are particularly evil and want to have some fun...

look at:

https://github.com/lakeman/trevisor

and

https://www1.informatik.uni-erlangen.de/tresor

Tresor does encryption/decryption using the x86 debug registers which are not usually visible to userland.

Trevisor is a bare metal hypervisor (bitvisor) with Tresor disk encryption...

It is a good and fairly understandable read and if security in your kernel is a must... then have it...

Re: memset_s

Posted: Fri Dec 30, 2016 6:01 am
by matt11235
dchapiesky wrote:Slightly off topic but the thread did start with a mention of security concerns...

If you are particularly evil and want to have some fun...

look at:

https://github.com/lakeman/trevisor

and

https://www1.informatik.uni-erlangen.de/tresor

Tresor does encryption/decryption using the x86 debug registers which are not usually visible to userland.

Trevisor is a bare metal hypervisor (bitvisor) with Tresor disk encryption...

It is a good and fairly understandable read and if security in your kernel is a must... then have it...
Trevisor looks really cool, and thank you for the advice.

Re: memset_s

Posted: Fri Dec 30, 2016 7:54 pm
by Love4Boobies
dchapiesky wrote:The problem is known as dead store removal and owasp has a page on it...

https://www.owasp.org/index.php/Insecur ... timization
The naive solution to that problem (that is probably mentioned in one of your other links) is to clear the password buffer via a volatile pointer or to use memset_s, which should not be optimized away. However, neither of these solutions are satisfactory. If security is your concern, there is nothing to guarantee that the program hasn't leaked the information some other way (e.g., by making a copy of the buffer for optimization purposes, by having the relevant pages swapped out to a (vulnerable) file at just the wrong time, etc.). Passwords shouldn't be in memory to begin with. Even when reading them in, you should be using a secure interface or, if you can't, at the very least minimize the risk of something going wrong by reading one character at a time and passing it through a one-way hash of some kind, which would allow for incremental computing.

Re: memset_s

Posted: Fri Dec 30, 2016 9:15 pm
by dchapiesky
Love4Boobies wrote:Passwords shouldn't be in memory to begin with. Even when reading them in, you should be using a secure interface or, if you can't, at the very least minimize the risk of something going wrong by reading one character at a time and passing it through a one-way hash of some kind, which would allow for incremental computing.
I agree... That is why I mentioned the Tresor project in my next post... basically encryption/decryption happens in the cpu registers without a memory footprint.

There is also a wonderful concept known as "Cache as RAM" which effectively uses cache... as RAM; again allowing encryption/decryption to happen without a memory footprint.

zenzizenzicube mentioned he has his own kernel, therefore either of these options is available to him and presumably he has control over paging.

While for userspace there are a significant number of tools for such things as taint analysis, binary analysis of just what is actually produced by the compiler is lacking. A few llvm projects work on bit-code but do not deal with actual object code generation.

However, for the adventurous there is the combination of the CompCert C Compiler and (as mentioned before, Frama-C)

http://compcert.inria.fr/compcert-C.html

http://frama-c.com/

In combination, you would use Frama-C to validate pre/post conditions and even your memory image pre/post conditions, inject applicable asserts(), etc... to verify your kernel actually does what you specified in your security assumptions.

Then compile actual object code using the CompCert C compiler - which is formally proven (they say) to produce object code that does exactly what the input C code described.

Together these would be a dream if only CompCert produced x86-64 code...

oh well