From: mancha <mancha1@zoho.com>
To: Stephan Mueller <smueller@chronox.de>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>,
Daniel Borkmann <daniel@iogearbox.net>,
tytso@mit.edu, linux-kernel@vger.kernel.org,
linux-crypto@vger.kernel.org, herbert@gondor.apana.org.au,
dborkman@redhat.com, cesarb@cesarb.eti.br
Subject: Re: [BUG/PATCH] kernel RNG and its secrets
Date: Wed, 18 Mar 2015 17:14:02 +0000 [thread overview]
Message-ID: <20150318171402.GB24195@zoho.com> (raw)
In-Reply-To: <4937031.1sk5yglzr8@tauon>
[-- Attachment #1.1: Type: text/plain, Size: 2740 bytes --]
On Wed, Mar 18, 2015 at 05:02:01PM +0100, Stephan Mueller wrote:
> Am Mittwoch, 18. März 2015, 16:09:34 schrieb Hannes Frederic Sowa:
>
> Hi Hannes,
>
> >On Wed, Mar 18, 2015, at 13:42, Daniel Borkmann wrote:
> >> On 03/18/2015 01:20 PM, Stephan Mueller wrote:
> >> > Am Mittwoch, 18. März 2015, 13:19:07 schrieb Hannes Frederic Sowa:
> >> >>>> My proposal would be to add a
> >> >>>>
> >> >>>> #define OPTIMIZER_HIDE_MEM(ptr, len) __asm__ __volatile__ ("" :
> >> >>>> :
> >> >>>> "m"(
> >> >>>> ({ struct { u8 b[len]; } *p = (void *)ptr ; *p; }) )
> >> >>>>
> >> >>>> and use this in the code function.
> >> >>>>
> >> >>>> This is documented in gcc manual 6.43.2.5.
> >> >>>
> >> >>> That one adds the zeroization instructuctions. But now there are
> >> >>> much
> >> >>> more than with the barrier.
> >> >>>
> >> >>> 400469: 48 c7 04 24 00 00 00 movq $0x0,(%rsp)
> >> >>> 400470: 00
> >> >>> 400471: 48 c7 44 24 08 00 00 movq $0x0,0x8(%rsp)
> >> >>> 400478: 00 00
> >> >>> 40047a: c7 44 24 10 00 00 00 movl $0x0,0x10(%rsp)
> >> >>> 400481: 00
> >> >>> 400482: 48 c7 44 24 20 00 00 movq $0x0,0x20(%rsp)
> >> >>> 400489: 00 00
> >> >>> 40048b: 48 c7 44 24 28 00 00 movq $0x0,0x28(%rsp)
> >> >>> 400492: 00 00
> >> >>> 400494: c7 44 24 30 00 00 00 movl $0x0,0x30(%rsp)
> >> >>> 40049b: 00
> >> >>>
> >> >>> Any ideas?
> >> >>
> >> >> Hmm, correct definition of u8?
> >> >
> >> > I use unsigned char
> >> >
> >> >> Which version of gcc do you use? I can't see any difference if I
> >> >> compile your example at -O2.
> >> >
> >> > gcc-Version 4.9.2 20150212 (Red Hat 4.9.2-6) (GCC)
> >
> >Well, was an error on my side, I see the same behavior.
> >
> >> I can see the same with the gcc version I previously posted. So
> >> it clears the 20 bytes from your example (movq, movq, movl) at
> >> two locations, presumably buf[] and b[].
> >
> >Yes, it looks like that. The reservation on the stack changes, too.
> >
> >Seems like just using barrier() is the best and easiest option.
>
> Would you prepare a patch for that?
> >
> >Thanks,
> >Hannes
>
>
> Ciao
> Stephan
Hi.
Patch 0001 fixes the dead store issue in memzero_explicit().
However, if the idea is to use barrier() instead of OPTIMIZER_HIDE_VAR()
in crypto_memneq() as well, then patch 0002 is the one to use. Please
review and keep in mind my analysis was limited to memzero_explicit().
Cesar, were there reasons you didn't use the gcc version of barrier()
for crypto_memneq()?
Please let me know if I can be of any further assistance.
--mancha
[-- Attachment #1.2: 0001-memzero_explicit.patch --]
[-- Type: text/plain, Size: 754 bytes --]
From cd9e882cd1d684f50c52471d83f9ecf55427c360 Mon Sep 17 00:00:00 2001
From: mancha security <mancha1@zoho.com>
Date: Wed, 18 Mar 2015 16:14:34 +0000
Subject: [PATCH] lib/string.c: use barrier() to protect memzero_explicit()
OPTIMIZER_HIDE_VAR(), as defined when using gcc, is insufficient
to ensure protection from dead store optimization.
---
lib/string.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/string.c b/lib/string.c
index ce81aae..a579201 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -607,7 +607,7 @@ EXPORT_SYMBOL(memset);
void memzero_explicit(void *s, size_t count)
{
memset(s, 0, count);
- OPTIMIZER_HIDE_VAR(s);
+ barrier();
}
EXPORT_SYMBOL(memzero_explicit);
--
2.1.4
[-- Attachment #1.3: 0002-OPTIMIZER_HIDE_VAR_purge.patch --]
[-- Type: text/plain, Size: 6288 bytes --]
From bca436d73ee5388be26488e3d2decdad1c6ba322 Mon Sep 17 00:00:00 2001
From: mancha security <mancha1@zoho.com>
Date: Wed, 18 Mar 2015 16:26:11 +0000
Subject: [PATCH] crypto: cyrpto_memneq and memzero_explicit
OPTIMIZER_HIDE_VAR(), as defined for gcc, is insufficient to protect
against certain compiler optimizations. Use barrier() instead.
---
crypto/memneq.c | 48 +++++++++++++++++++++---------------------
include/linux/compiler-gcc.h | 3 ---
include/linux/compiler-intel.h | 7 ------
include/linux/compiler.h | 4 ----
lib/string.c | 2 +-
5 files changed, 25 insertions(+), 39 deletions(-)
diff --git a/crypto/memneq.c b/crypto/memneq.c
index afed1bd..efa7750 100644
--- a/crypto/memneq.c
+++ b/crypto/memneq.c
@@ -72,7 +72,7 @@ __crypto_memneq_generic(const void *a, const void *b, size_t size)
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
while (size >= sizeof(unsigned long)) {
neq |= *(unsigned long *)a ^ *(unsigned long *)b;
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
a += sizeof(unsigned long);
b += sizeof(unsigned long);
size -= sizeof(unsigned long);
@@ -80,7 +80,7 @@ __crypto_memneq_generic(const void *a, const void *b, size_t size)
#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
while (size > 0) {
neq |= *(unsigned char *)a ^ *(unsigned char *)b;
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
a += 1;
b += 1;
size -= 1;
@@ -96,53 +96,53 @@ static inline unsigned long __crypto_memneq_16(const void *a, const void *b)
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
if (sizeof(unsigned long) == 8) {
neq |= *(unsigned long *)(a) ^ *(unsigned long *)(b);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned long *)(a+8) ^ *(unsigned long *)(b+8);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
} else if (sizeof(unsigned int) == 4) {
neq |= *(unsigned int *)(a) ^ *(unsigned int *)(b);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned int *)(a+4) ^ *(unsigned int *)(b+4);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned int *)(a+8) ^ *(unsigned int *)(b+8);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned int *)(a+12) ^ *(unsigned int *)(b+12);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
} else
#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
{
neq |= *(unsigned char *)(a) ^ *(unsigned char *)(b);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+1) ^ *(unsigned char *)(b+1);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+2) ^ *(unsigned char *)(b+2);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+3) ^ *(unsigned char *)(b+3);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+4) ^ *(unsigned char *)(b+4);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+5) ^ *(unsigned char *)(b+5);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+6) ^ *(unsigned char *)(b+6);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+7) ^ *(unsigned char *)(b+7);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+8) ^ *(unsigned char *)(b+8);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+9) ^ *(unsigned char *)(b+9);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+10) ^ *(unsigned char *)(b+10);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+11) ^ *(unsigned char *)(b+11);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+12) ^ *(unsigned char *)(b+12);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+13) ^ *(unsigned char *)(b+13);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+14) ^ *(unsigned char *)(b+14);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
neq |= *(unsigned char *)(a+15) ^ *(unsigned char *)(b+15);
- OPTIMIZER_HIDE_VAR(neq);
+ barrier();
}
return neq;
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index cdf13ca..d4c15f0 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -37,9 +37,6 @@
__asm__ ("" : "=r"(__ptr) : "0"(ptr)); \
(typeof(ptr)) (__ptr + (off)); })
-/* Make the optimizer believe the variable can be manipulated arbitrarily. */
-#define OPTIMIZER_HIDE_VAR(var) __asm__ ("" : "=r" (var) : "0" (var))
-
#ifdef __CHECKER__
#define __must_be_array(arr) 0
#else
diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h
index ba147a1..140211e 100644
--- a/include/linux/compiler-intel.h
+++ b/include/linux/compiler-intel.h
@@ -14,19 +14,12 @@
* It uses intrinsics to do the equivalent things.
*/
#undef RELOC_HIDE
-#undef OPTIMIZER_HIDE_VAR
#define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
__ptr = (unsigned long) (ptr); \
(typeof(ptr)) (__ptr + (off)); })
-/* This should act as an optimization barrier on var.
- * Given that this compiler does not have inline assembly, a compiler barrier
- * is the best we can do.
- */
-#define OPTIMIZER_HIDE_VAR(var) barrier()
-
/* Intel ECC compiler doesn't support __builtin_types_compatible_p() */
#define __must_be_array(a) 0
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 1b45e4a..b70f303 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -181,10 +181,6 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
(typeof(ptr)) (__ptr + (off)); })
#endif
-#ifndef OPTIMIZER_HIDE_VAR
-#define OPTIMIZER_HIDE_VAR(var) barrier()
-#endif
-
/* Not-quite-unique ID. */
#ifndef __UNIQUE_ID
# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
diff --git a/lib/string.c b/lib/string.c
index ce81aae..a579201 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -607,7 +607,7 @@ EXPORT_SYMBOL(memset);
void memzero_explicit(void *s, size_t count)
{
memset(s, 0, count);
- OPTIMIZER_HIDE_VAR(s);
+ barrier();
}
EXPORT_SYMBOL(memzero_explicit);
--
2.1.4
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
next prev parent reply other threads:[~2015-03-18 17:18 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-18 9:53 [BUG/PATCH] kernel RNG and its secrets mancha
2015-03-18 10:30 ` Daniel Borkmann
2015-03-18 10:50 ` Hannes Frederic Sowa
2015-03-18 10:56 ` Daniel Borkmann
2015-03-18 11:09 ` Stephan Mueller
2015-03-18 12:02 ` Hannes Frederic Sowa
2015-03-18 12:14 ` Stephan Mueller
2015-03-18 12:19 ` Hannes Frederic Sowa
2015-03-18 12:20 ` Stephan Mueller
2015-03-18 12:42 ` Daniel Borkmann
2015-03-18 15:09 ` Hannes Frederic Sowa
2015-03-18 16:02 ` Stephan Mueller
2015-03-18 17:14 ` mancha [this message]
2015-03-18 17:49 ` Daniel Borkmann
2015-03-18 19:09 ` mancha
2015-03-18 23:53 ` Cesar Eduardo Barros
2015-03-18 17:41 ` Theodore Ts'o
2015-03-18 17:56 ` Hannes Frederic Sowa
2015-03-18 17:58 ` Theodore Ts'o
2015-03-18 12:58 ` mancha
2015-04-10 13:25 ` Stephan Mueller
2015-04-10 14:00 ` Hannes Frederic Sowa
2015-04-10 14:09 ` Stephan Mueller
2015-04-10 14:22 ` mancha security
2015-04-10 14:33 ` Stephan Mueller
2015-04-10 20:09 ` mancha security
2015-04-10 14:26 ` Hannes Frederic Sowa
2015-04-10 14:36 ` Stephan Mueller
2015-04-10 14:45 ` Hannes Frederic Sowa
2015-04-10 14:46 ` Daniel Borkmann
2015-04-10 14:50 ` Stephan Mueller
2015-04-10 14:54 ` Daniel Borkmann
2015-04-27 19:10 ` Stephan Mueller
2015-04-27 20:34 ` Daniel Borkmann
2015-04-27 20:41 ` Stephan Mueller
2015-04-27 20:53 ` Daniel Borkmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150318171402.GB24195@zoho.com \
--to=mancha1@zoho.com \
--cc=cesarb@cesarb.eti.br \
--cc=daniel@iogearbox.net \
--cc=dborkman@redhat.com \
--cc=hannes@stressinduktion.org \
--cc=herbert@gondor.apana.org.au \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=smueller@chronox.de \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.