-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Switch memory_cleanse implementation to BoringSSL's to ensure memory clearing even with -lto #11196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
sipa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Big concept ACK; there's no need to use OpenSSL for something as simple as this
src/support/cleanse.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment doesn't seem to apply in the current form of the code.
src/support/cleanse.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure OpenSSL's headers expose such a macro, and even if they do, this risks breaking things if OpenSSL gets removed entirely at some point. I believe you just want _MSC_VER here to detect MSVC (as the else branch should work fine in MinGW).
084674d to
9c4f8b5
Compare
|
Nits addressed (don't push code late at night!) |
|
Concept ACK! Too bad there is no bulletproof way to detect |
|
utACK 9c4f8b5188a53f39c0849f860c8227fbb5a77bc6 |
|
Concept ACK - minimizing OpenSSL exposure is good. ISC seems less strict than even MIT, appears compatible. |
|
Concept ACK |
|
concept ACK. and utACK 9c4f8b5188a53f39c0849f860c8227fbb5a77bc6. It'll be great to be rid of the openssl dependency at such a low level. The logic seems sane. It'd be nice if we could add a test, but I suppose we can't test reliably without affecting the outcome. |
|
@cfields you can review the ASM at least. |
|
utACK 9c4f8b5188a53f39c0849f860c8227fbb5a77bc6 |
src/support/cleanse.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does a bare __asm do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presumbly the same as the GCC extended asm block above, and hopefully prevents the code from being optimized out.
However, I'm not sure to what extent we want to support MSVC, especially as __asm is only supported on x86, not x86_64.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, I'm not sure to what extent we want to support MSVC, especially as __asm is only supported on x86, not x86_64.
We don't support MSVC (I don't know of any dev who cares to maintain support for it) however It shouldn't be unnecessarily difficult to build with it, so if possible we should try to be compatible with it.
|
Concept ACK, though I don't understand why this works (certainly in the MSCV case), I would prefer a more explanatory comment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK
I tried this. This code: https://gist.github.com/kallewoof/200748b8093194135c91074ef8929a5b compiled with g++ -O3 -S results in this assembly output:
https://gist.github.com/kallewoof/8b7501ea561c8363757abd52dd547f84 (macOS) https://gist.github.com/kallewoof/1edc1d2dfffd6b9cbd4b894b17da86fc (ubu17.04)
whereas if the asm stuff is commented out, you get this:
https://gist.github.com/kallewoof/531384f4e577a2b10b4f3f88e638547c (macOS) https://gist.github.com/kallewoof/75846ad463cb5ab1954d90705a41452f (ubu17.04)
(The movqs at lines 45-48 (macOS first assembly) are zeroing the data in the first assembly output.)
I also tried the
{
char x[32];
sprintf(x, "1234567890123456789012345678901");
memory_cleanse(x, 32);
}variant, and it gives the same results. The assembly output is slightly different though: https://gist.github.com/kallewoof/b733a0a1f8d430d935e268347de17633
src/support/cleanse.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
μNit: Maybe <cstring> instead, since this is C++.
|
Since we - in contrast to BoringSSL - have the luxury of always compiling with assertions enabled, what about also adding an assertion |
|
@practicalswift: I think that affects the resulting code. It basically skips cleans for untouched memory. By touching memory it will forego that optimization. |
…clearing even with link-time optimization. The implementation we currently use from OpenSSL prevents the compiler from optimizing away clensing operations on blocks of memory that are about to be released, but this protection is not extended to link-time optimization. This commit copies the solution cooked up by Google compiler engineers which uses inline assembly directives to instruct the compiler not to optimize out the call under any circumstances. As the code is in-lined, this has the added advantage of removing one more OpenSSL dependency. Regarding license compatibility, Google's contributions to BoringSSL library, including this code, is made available under the ISC license, which is MIT compatible. BoringSSL git commit: ad1907fe73334d6c696c8539646c21b11178f20f
16770aa to
1444c2e
Compare
|
In the original boringssl review at https://boringssl-review.googlesource.com/c/boringssl/+/1339 it was noted that on WIndows its likely better to just use SecureZeroMemory...maybe do that in place of the string __asm for MSVC? |
|
I vaguely remember there was something wrong/insecure about SecureZeroMemory but I can't remember what and a quick search doesn't turn up anything. I think it was something with being a Win32 API function (syscall) so it makes it easier for malware to hook the function and scoop up all the sensitive data. Anyhow, I don't know if it matters. |
|
Should I switch to SecureZeroMemory on windows? I don't know enough about windows to evaluate that risk. Or is this ready to merge as-is? |
|
I think this is fine as-is. utACK 1444c2e |
I also think it's fine as it is. Note that @TheBlueMatt doesn't say to use that call generally on Windows, but specifically on MSVC. Someone that maintains MSVC support should do the evaluation of the subtleties for what function/method to use there. Just using BoringSSL's code is "best effort" to support it as anything. (also, if they make another decision re: MSVC we can always take it over) |
…ensure memory clearing even with -lto 1444c2e Switch memory_cleanse implementation to BoringSSL's to ensure memory clearing even with link-time optimization. (Adam Langley) Pull request description: The implementation we currently use from OpenSSL prevents the compiler from optimizing away clensing operations on blocks of memory that are about to be released, but this protection is not extended to link-time optimization. This commit copies the solution cooked up by Google compiler engineers which uses inline assembly directives to instruct the compiler not to optimize out the call under any circumstances. As the code is in-lined, this has the added advantage of removing one more OpenSSL dependency. Regarding license compatibility, Google's contributions to BoringSSL library, including this code, is made available under the ISC license, which is MIT compatible. BoringSSL git commit: ad1907fe73334d6c696c8539646c21b11178f20f Tree-SHA512: 8134998663c1501e3ce48fbbd6ab41de981f0855e3f4d25d2e86ff8056c917d82c751c88e9c39660319ebfbc8283dce594c3e4fc7f87080a212a2cdba57ea511
…L's to ensure memory clearing even with -lto 1444c2e Switch memory_cleanse implementation to BoringSSL's to ensure memory clearing even with link-time optimization. (Adam Langley) Pull request description: The implementation we currently use from OpenSSL prevents the compiler from optimizing away clensing operations on blocks of memory that are about to be released, but this protection is not extended to link-time optimization. This commit copies the solution cooked up by Google compiler engineers which uses inline assembly directives to instruct the compiler not to optimize out the call under any circumstances. As the code is in-lined, this has the added advantage of removing one more OpenSSL dependency. Regarding license compatibility, Google's contributions to BoringSSL library, including this code, is made available under the ISC license, which is MIT compatible. BoringSSL git commit: ad1907fe73334d6c696c8539646c21b11178f20f Tree-SHA512: 8134998663c1501e3ce48fbbd6ab41de981f0855e3f4d25d2e86ff8056c917d82c751c88e9c39660319ebfbc8283dce594c3e4fc7f87080a212a2cdba57ea511
Memory cleanse backports Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#10308 - bitcoin/bitcoin#11196 - bitcoin/bitcoin#11558 - Only the changes that did not conflict. - bitcoin/bitcoin#16158 Part of #145.
memory_cleanse backports Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#10308 - bitcoin/bitcoin#11196 - bitcoin/bitcoin#11558 - Only the changes that did not conflict. - bitcoin/bitcoin#16158 Part of #145.
Summary: ...to ensure memory clearing even with link-time optimization. ``` The implementation we currently use from OpenSSL prevents the compiler from optimizing away clensing operations on blocks of memory that are about to be released, but this protection is not extended to link-time optimization. This commit copies the solution cooked up by Google compiler engineers which uses inline assembly directives to instruct the compiler not to optimize out the call under any circumstances. As the code is in-lined, this has the added advantage of removing one more OpenSSL dependency. Regarding license compatibility, Google's contributions to BoringSSL library, including this code, is made available under the ISC license, which is MIT compatible. BoringSSL git commit: ad1907fe73334d6c696c8539646c21b11178f20f ``` Backport of core [[bitcoin/bitcoin#11196 | PR11196]]. Test Plan: ninja all check Run the windows Gitian build. Reviewers: #bitcoin_abc, deadalnix Reviewed By: #bitcoin_abc, deadalnix Subscribers: deadalnix Differential Revision: https://reviews.bitcoinabc.org/D6135
Summary: ...to ensure memory clearing even with link-time optimization. ``` The implementation we currently use from OpenSSL prevents the compiler from optimizing away clensing operations on blocks of memory that are about to be released, but this protection is not extended to link-time optimization. This commit copies the solution cooked up by Google compiler engineers which uses inline assembly directives to instruct the compiler not to optimize out the call under any circumstances. As the code is in-lined, this has the added advantage of removing one more OpenSSL dependency. Regarding license compatibility, Google's contributions to BoringSSL library, including this code, is made available under the ISC license, which is MIT compatible. BoringSSL git commit: ad1907fe73334d6c696c8539646c21b11178f20f ``` Backport of core [[bitcoin/bitcoin#11196 | PR11196]]. Test Plan: ninja all check Run the windows Gitian build. Reviewers: #bitcoin_abc, deadalnix Reviewed By: #bitcoin_abc, deadalnix Subscribers: deadalnix Differential Revision: https://reviews.bitcoinabc.org/D6135
The implementation we currently use from OpenSSL prevents the compiler from optimizing away clensing operations on blocks of memory that are about to be released, but this protection is not extended to link-time optimization. This commit copies the solution cooked up by Google compiler engineers which uses inline assembly directives to instruct the compiler not to optimize out the call under any circumstances. As the code is in-lined, this has the added advantage of removing one more OpenSSL dependency.
Regarding license compatibility, Google's contributions to BoringSSL library, including this code, is made available under the ISC license, which is MIT compatible.
BoringSSL git commit: ad1907fe73334d6c696c8539646c21b11178f20f