Commit d4c5efdb authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Theodore Ts'o

random: add and use memzero_explicit() for clearing data

zatimend has reported that in his environment (3.16/gcc4.8.3/corei7)
memset() calls which clear out sensitive data in extract_{buf,entropy,
entropy_user}() in random driver are being optimized away by gcc.

Add a helper memzero_explicit() (similarly as explicit_bzero() variants)
that can be used in such cases where a variable with sensitive data is
being cleared out in the end. Other use cases might also be in crypto
code. [ I have put this into lib/string.c though, as it's always built-in
and doesn't need any dependencies then. ]

Fixes kernel bugzilla: 82041

Reported-by: zatimend@hotmail.co.uk
Signed-off-by: default avatarDaniel Borkmann <dborkman@redhat.com>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Cc: stable@vger.kernel.org
parent 7d1311b9
...@@ -1106,7 +1106,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out) ...@@ -1106,7 +1106,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
__mix_pool_bytes(r, hash.w, sizeof(hash.w)); __mix_pool_bytes(r, hash.w, sizeof(hash.w));
spin_unlock_irqrestore(&r->lock, flags); spin_unlock_irqrestore(&r->lock, flags);
memset(workspace, 0, sizeof(workspace)); memzero_explicit(workspace, sizeof(workspace));
/* /*
* In case the hash function has some recognizable output * In case the hash function has some recognizable output
...@@ -1118,7 +1118,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out) ...@@ -1118,7 +1118,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
hash.w[2] ^= rol32(hash.w[2], 16); hash.w[2] ^= rol32(hash.w[2], 16);
memcpy(out, &hash, EXTRACT_SIZE); memcpy(out, &hash, EXTRACT_SIZE);
memset(&hash, 0, sizeof(hash)); memzero_explicit(&hash, sizeof(hash));
} }
/* /*
...@@ -1175,7 +1175,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, ...@@ -1175,7 +1175,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
} }
/* Wipe data just returned from memory */ /* Wipe data just returned from memory */
memset(tmp, 0, sizeof(tmp)); memzero_explicit(tmp, sizeof(tmp));
return ret; return ret;
} }
...@@ -1218,7 +1218,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, ...@@ -1218,7 +1218,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
} }
/* Wipe data just returned from memory */ /* Wipe data just returned from memory */
memset(tmp, 0, sizeof(tmp)); memzero_explicit(tmp, sizeof(tmp));
return ret; return ret;
} }
......
...@@ -144,7 +144,8 @@ static inline bool strstarts(const char *str, const char *prefix) ...@@ -144,7 +144,8 @@ static inline bool strstarts(const char *str, const char *prefix)
return strncmp(str, prefix, strlen(prefix)) == 0; return strncmp(str, prefix, strlen(prefix)) == 0;
} }
extern size_t memweight(const void *ptr, size_t bytes); size_t memweight(const void *ptr, size_t bytes);
void memzero_explicit(void *s, size_t count);
/** /**
* kbasename - return the last part of a pathname. * kbasename - return the last part of a pathname.
......
...@@ -604,6 +604,22 @@ void *memset(void *s, int c, size_t count) ...@@ -604,6 +604,22 @@ void *memset(void *s, int c, size_t count)
EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memset);
#endif #endif
/**
* memzero_explicit - Fill a region of memory (e.g. sensitive
* keying data) with 0s.
* @s: Pointer to the start of the area.
* @count: The size of the area.
*
* memzero_explicit() doesn't need an arch-specific version as
* it just invokes the one of memset() implicitly.
*/
void memzero_explicit(void *s, size_t count)
{
memset(s, 0, count);
OPTIMIZER_HIDE_VAR(s);
}
EXPORT_SYMBOL(memzero_explicit);
#ifndef __HAVE_ARCH_MEMCPY #ifndef __HAVE_ARCH_MEMCPY
/** /**
* memcpy - Copy one area of memory to another * memcpy - Copy one area of memory to another
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment