From 2d5848200404b2773c35bb1aa00dc3edd7a829d9 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Thu, 15 Dec 2016 15:45:11 -0800 Subject: [PATCH] Call __msan_unpoison on the output of getrandom. MSAN doesn't hook |syscall| and thus doesn't know that the kernel has filled the output buffer when |getrandom| is called. This change tells MSAN to trust that the memory that |getrandom| writes to has been initialised. This should avoid false-positives when code operates on |RAND_bytes| output. Change-Id: I0a74ebb21bcd1de1f28eda69558ee27f82db807a Reviewed-on: https://boringssl-review.googlesource.com/12903 Reviewed-by: Adam Langley Commit-Queue: Adam Langley CQ-Verified: CQ bot account: commit-bot@chromium.org --- crypto/rand/urandom.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/crypto/rand/urandom.c b/crypto/rand/urandom.c index 14d2e8a3..26feec73 100644 --- a/crypto/rand/urandom.c +++ b/crypto/rand/urandom.c @@ -237,18 +237,35 @@ static struct rand_buffer *get_thread_local_buffer(void) { return buf; } +#if defined(USE_SYS_getrandom) && defined(__has_feature) +#if __has_feature(memory_sanitizer) +void __msan_unpoison(void *, size_t); +#endif +#endif + /* fill_with_entropy writes |len| bytes of entropy into |out|. It returns one * on success and zero on error. */ static char fill_with_entropy(uint8_t *out, size_t len) { - ssize_t r; - while (len > 0) { + ssize_t r; + if (urandom_fd == kHaveGetrandom) { #if defined(USE_SYS_getrandom) do { r = syscall(SYS_getrandom, out, len, 0 /* no flags */); } while (r == -1 && errno == EINTR); -#else + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) + if (r > 0) { + /* MSAN doesn't recognise |syscall| and thus doesn't notice that we + * have initialised the output buffer. */ + __msan_unpoison(out, r); + } +#endif /* memory_sanitizer */ +#endif /*__has_feature */ + +#else /* USE_SYS_getrandom */ abort(); #endif } else {