Skip to content

Conversation

nobled
Copy link
Contributor

@nobled nobled commented Nov 26, 2011

This finishes a TODO comment:
// TODO: mlock memory / munlock on return so they will not be swapped out, really need "mlockedstring" wrapper class to do this safely

SecureString is identical to std::string except with secure_allocator
substituting for std::allocator. This makes casting between them
impossible, so converting between the two at API boundaries requires
calling ::c_str() for now.

The lack of implicit casting between the two was a big advantage in making this patch thorough, since the build would break if not all the prototypes were updated. So it should also be a 'feature' in making sure implicit casts (meaning gratuitous copies into non-locked memory) aren't accidentally introduced in the future.

Passphrases are now only copied from non-locked memory in askpassphrasedialog.cpp (from Qt's QLineEdit / QString) and in bitcoinrpc.cpp (from whatever library is providing Array; I couldn't tell).

SecureString is identical to std::string except with secure_allocator
substituting for std::allocator. This makes casting between them
impossible, so converting between the two at API boundaries requires
calling ::c_str() for now.
@laanwj
Copy link
Member

laanwj commented Nov 26, 2011

Improves security AND makes the code more readable, I like this.

ACK.

@laanwj
Copy link
Member

laanwj commented Nov 26, 2011

Using ::c_cstr at API boundaries does have the drawback that '\0' characters are not allowed -- the canonical form of converting between string types is to use data() and size(), or .begin()/.end(). Then again, I don't think you can enter those in form fields anyway :)

@TheBlueMatt
Copy link
Contributor

Though it does make some code a bit easier to read, it is no more secure (in fact, with the additional conversions, one could argue its less secure, though not really). Anyway, meh.

@laanwj
Copy link
Member

laanwj commented Nov 26, 2011

Less secure? How?

@TheBlueMatt
Copy link
Contributor

.get_str().c_str() instead of .get_str() in several places means the string (likely) gets copied twice in memory instead of once.

@laanwj
Copy link
Member

laanwj commented Nov 26, 2011

I really don't see how this could make things less secure.

  • By passing all the passphrases as SecureString all the way into the CWallet API, this makes sure the passphrases only exist in mlocked memory (except in Qt and inside the JSON parser, but that was already the case before, and in the case of Qt there is little to do against it). Before, they were passed in plain std::strings.
  • As I understand the conversions don't cause any extra allocation/deallocation of insecure memory, the conversions just pass memory around (and there's not that many more) from one mlocked area to another, which is filled with zeros before freeing.
  • By using a specific SecureString type it is signaled clearly that the data inside it should be handled with care.

Sigh, seems that sometimes you just want to disagree with things for the sake of disagreeing... do you really like arguing that much?

@laanwj
Copy link
Member

laanwj commented Nov 26, 2011

No, it does not copy anything (it can't, where would it copy to?). c_str() simply returns a pointer to the data inside the string.

@TheBlueMatt
Copy link
Contributor

re: 1 yes, but those strings were previously mlocked, so no security is gained.

re: 2 yes, that is my bad, I had just forgotten that those were returning pointers, not creating new objects...just my C++ inexperience showing...

@TheBlueMatt
Copy link
Contributor

Let my rephrase my original comment:
Makes code easier to read, but doesnt add security, probably worth pulling. Meh.

@laanwj
Copy link
Member

laanwj commented Nov 26, 2011

  1. In the case of bitcoin-qt they weren't. That was my reason for saying this is more secure.

  2. STL has a bad name from the MSVC 6.0 implementation, but luckily is not that inefficient :)

Also this makes it harder to forget manually mlocking/munlocking (or maybe worse, skipping munlocking in the case of an exception so that memory stays locked indefinitely) in future usages of the API.

gavinandresen added a commit that referenced this pull request Dec 1, 2011
Implement an mlock()'d string class for storing passphrases
@gavinandresen gavinandresen merged commit a7120a3 into bitcoin:master Dec 1, 2011
coblee referenced this pull request in litecoin-project/litecoin Jul 17, 2012
Implement an mlock()'d string class for storing passphrases
ptschip pushed a commit to ptschip/bitcoin that referenced this pull request Jun 12, 2017
Relax ban for Initial Header download
Losangelosgenetics pushed a commit to Losangelosgenetics/bitcoin that referenced this pull request Mar 12, 2020
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants