smemclr.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /*
  2. * Securely wipe memory.
  3. *
  4. * The actual wiping is no different from what memset would do: the
  5. * point of 'securely' is to try to be sure over-clever compilers
  6. * won't optimise away memsets on variables that are about to be freed
  7. * or go out of scope. See
  8. * https://buildsecurityin.us-cert.gov/bsi-rules/home/g1/771-BSI.html
  9. */
  10. #include "defs.h"
  11. #include "misc.h"
  12. /*
  13. * Trivial function that is given a pointer to some memory and ignores
  14. * it.
  15. */
  16. static void no_op(void *ptr, size_t size) {}
  17. /*
  18. * Function pointer that is given a pointer to some memory, and from
  19. * the compiler's point of view, _might_ read it, or otherwise depend
  20. * on its contents.
  21. *
  22. * In fact, this function pointer always points to no_op() above. But
  23. * because the pointer itself is volatile-qualified, the compiler
  24. * isn't allowed to optimise based on the assumption that that will
  25. * always be the case. So it has to call through the function pointer
  26. * anyway, on the basis that it _might_ have magically changed at run
  27. * time into a pointer to some completely arbitrary function. And
  28. * therefore it must also avoid optimising away any observable effect
  29. * beforehand that a completely arbitrary function might depend on -
  30. * such as the zeroing of our memory region.
  31. */
  32. static void (*const volatile maybe_read)(void *ptr, size_t size) = no_op;
  33. void smemclr(void *b, size_t n)
  34. {
  35. if (b && n > 0) {
  36. /*
  37. * Zero out the memory.
  38. */
  39. memset(b, 0, n);
  40. /*
  41. * Call the above function pointer, which (for all the
  42. * compiler knows) might check that we've really zeroed the
  43. * memory.
  44. */
  45. maybe_read(b, n);
  46. }
  47. }