Commit d4c5efdb97773f59a2b711754ca0953f24516739
Committed by
Theodore Ts'o
1 parent
7d1311b93e
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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: Daniel Borkmann <dborkman@redhat.com> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Cc: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@vger.kernel.org
Showing 3 changed files with 23 additions and 6 deletions Side-by-side Diff
drivers/char/random.c
... | ... | @@ -1106,7 +1106,7 @@ |
1106 | 1106 | __mix_pool_bytes(r, hash.w, sizeof(hash.w)); |
1107 | 1107 | spin_unlock_irqrestore(&r->lock, flags); |
1108 | 1108 | |
1109 | - memset(workspace, 0, sizeof(workspace)); | |
1109 | + memzero_explicit(workspace, sizeof(workspace)); | |
1110 | 1110 | |
1111 | 1111 | /* |
1112 | 1112 | * In case the hash function has some recognizable output |
... | ... | @@ -1118,7 +1118,7 @@ |
1118 | 1118 | hash.w[2] ^= rol32(hash.w[2], 16); |
1119 | 1119 | |
1120 | 1120 | memcpy(out, &hash, EXTRACT_SIZE); |
1121 | - memset(&hash, 0, sizeof(hash)); | |
1121 | + memzero_explicit(&hash, sizeof(hash)); | |
1122 | 1122 | } |
1123 | 1123 | |
1124 | 1124 | /* |
... | ... | @@ -1175,7 +1175,7 @@ |
1175 | 1175 | } |
1176 | 1176 | |
1177 | 1177 | /* Wipe data just returned from memory */ |
1178 | - memset(tmp, 0, sizeof(tmp)); | |
1178 | + memzero_explicit(tmp, sizeof(tmp)); | |
1179 | 1179 | |
1180 | 1180 | return ret; |
1181 | 1181 | } |
... | ... | @@ -1218,7 +1218,7 @@ |
1218 | 1218 | } |
1219 | 1219 | |
1220 | 1220 | /* Wipe data just returned from memory */ |
1221 | - memset(tmp, 0, sizeof(tmp)); | |
1221 | + memzero_explicit(tmp, sizeof(tmp)); | |
1222 | 1222 | |
1223 | 1223 | return ret; |
1224 | 1224 | } |
include/linux/string.h
... | ... | @@ -132,7 +132,7 @@ |
132 | 132 | #endif |
133 | 133 | |
134 | 134 | extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, |
135 | - const void *from, size_t available); | |
135 | + const void *from, size_t available); | |
136 | 136 | |
137 | 137 | /** |
138 | 138 | * strstarts - does @str start with @prefix? |
... | ... | @@ -144,7 +144,8 @@ |
144 | 144 | return strncmp(str, prefix, strlen(prefix)) == 0; |
145 | 145 | } |
146 | 146 | |
147 | -extern size_t memweight(const void *ptr, size_t bytes); | |
147 | +size_t memweight(const void *ptr, size_t bytes); | |
148 | +void memzero_explicit(void *s, size_t count); | |
148 | 149 | |
149 | 150 | /** |
150 | 151 | * kbasename - return the last part of a pathname. |
lib/string.c
... | ... | @@ -604,6 +604,22 @@ |
604 | 604 | EXPORT_SYMBOL(memset); |
605 | 605 | #endif |
606 | 606 | |
607 | +/** | |
608 | + * memzero_explicit - Fill a region of memory (e.g. sensitive | |
609 | + * keying data) with 0s. | |
610 | + * @s: Pointer to the start of the area. | |
611 | + * @count: The size of the area. | |
612 | + * | |
613 | + * memzero_explicit() doesn't need an arch-specific version as | |
614 | + * it just invokes the one of memset() implicitly. | |
615 | + */ | |
616 | +void memzero_explicit(void *s, size_t count) | |
617 | +{ | |
618 | + memset(s, 0, count); | |
619 | + OPTIMIZER_HIDE_VAR(s); | |
620 | +} | |
621 | +EXPORT_SYMBOL(memzero_explicit); | |
622 | + | |
607 | 623 | #ifndef __HAVE_ARCH_MEMCPY |
608 | 624 | /** |
609 | 625 | * memcpy - Copy one area of memory to another |
-
mentioned in commit b0bb7f
-
mentioned in commit b0bb7f
-
mentioned in commit b0bb7f
-
mentioned in commit b0bb7f
-
mentioned in commit 35394c
-
mentioned in commit b0bb7f
-
mentioned in commit 35394c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c
-
mentioned in commit 0b053c