Mailing List Archive

[PATCH 1/2] common/mischelp: use memset for wipememory
* common/mischelp.h (wipememory2): Replace macro with function
prototype.
* common/mischelp.c (wipememory2): New.
--

In new wipememory2 function, memset is called through volatile
function pointer to so that compiler won't optimize away the call.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
---
common/mischelp.c | 10 ++++++++++
common/mischelp.h | 12 ++++--------
2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/common/mischelp.c b/common/mischelp.c
index 75ba60714..008aaab55 100644
--- a/common/mischelp.c
+++ b/common/mischelp.c
@@ -49,6 +49,16 @@
#include "mischelp.h"


+void
+wipememory2 (void *ptr, int set, size_t len)
+{
+ /* Prevent compiler from optimizing away the call to memset by accessing
+ memset through volatile pointer. */
+ static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset;
+ memset_ptr (ptr, set, len);
+}
+
+
/* Check whether the files NAME1 and NAME2 are identical. This is for
example achieved by comparing the inode numbers of the files. */
int
diff --git a/common/mischelp.h b/common/mischelp.h
index 18ec96edf..2554c2160 100644
--- a/common/mischelp.h
+++ b/common/mischelp.h
@@ -47,14 +47,10 @@ time_t timegm (struct tm *tm);
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define DIMof(type,member) DIM(((type *)0)->member)

-/* To avoid that a compiler optimizes certain memset calls away, these
- macros may be used instead. */
-#define wipememory2(_ptr,_set,_len) do { \
- volatile char *_vptr=(volatile char *)(_ptr); \
- size_t _vlen=(_len); \
- while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
- } while(0)
-#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+/* To avoid that a compiler optimizes certain memset calls away,
+ wipememory function and macro may be used instead. */
+void wipememory2(void *ptr, int set, size_t len);
+#define wipememory(_ptr,_len) wipememory2((_ptr),0,(_len))


/* Include hacks which are mainly required for Slowaris. */


_______________________________________________
Gnupg-devel mailing list
Gnupg-devel@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-devel
Re: [PATCH 1/2] common/mischelp: use memset for wipememory [ In reply to ]
On Fri, 9 Nov 2018 17:48, jussi.kivilinna@iki.fi said:

> In new wipememory2 function, memset is called through volatile
> function pointer to so that compiler won't optimize away the call.

<rant>Are you sure that none of those braindead compilers removes that call
for example when inlined? They may find yet another interpreation why
it is allowed. But anyway, the old code would or is already target to
such new dis-optimization.</>


Salam-Shalom,

Werner

--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Re: [PATCH 1/2] common/mischelp: use memset for wipememory [ In reply to ]
On 13.11.2018 17.20, Werner Koch wrote:
> On Fri, 9 Nov 2018 17:48, jussi.kivilinna@iki.fi said:
>
>> In new wipememory2 function, memset is called through volatile
>> function pointer to so that compiler won't optimize away the call.
>
> <rant>Are you sure that none of those braindead compilers removes that call
> for example when inlined? They may find yet another interpreation why
> it is allowed. But anyway, the old code would or is already target to
> such new dis-optimization.</>

Well, sufficiently braindead compiler might check if value read from volatile
function pointer is for 'memset' and do dead store elimination. In practice,
this does not happen. Access to memset through volatile pointer is discussed
here:
http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
http://www.daemonology.net/blog/2014-09-05-erratum.html

Best way to perform memory wipe would be through platform provided functions,
such as explicit_bzero, or memset_s. I'll add support those and leave
volatile function pointer approach as backup.

-Jussi