Skip to content

Commit

Permalink
Clamp walletpassphrase timeout to 2^(30) seconds and check its bounds
Browse files Browse the repository at this point in the history
Clamps the timeout of walletpassphrase to 2^(30) seconds, which is
~34 years. Any number greater than that will be forced to be
2^(30). This avoids the sign flipping problem with large values which
can result in a negative time used.

Also perform bounds checks to ensure that the timeout is positive
to avoid immediate relocking of the wallet.
  • Loading branch information
achow101 committed Jan 12, 2018
1 parent 5691028 commit 0b63e3c
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2269,7 +2269,8 @@ UniValue walletpassphrase(const JSONRPCRequest& request)
"This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
"\nArguments:\n"
"1. \"passphrase\" (string, required) The wallet passphrase\n"
"2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
"2. timeout (numeric, required) The time to keep the decryption key in seconds. Limited to at most 1073741824 (2^30) seconds.\n"
" Any value greater than 1073741824 seconds will be set to 1073741824 seconds.\n"
"\nNote:\n"
"Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
"time that overrides the old one.\n"
Expand Down Expand Up @@ -2298,6 +2299,17 @@ UniValue walletpassphrase(const JSONRPCRequest& request)
// Alternately, find a way to make request.params[0] mlock()'d to begin with.
strWalletPass = request.params[0].get_str().c_str();

// Get the timeout
int64_t nSleepTime = request.params[1].get_int64();
// Timeout cannot be negative, otherwise it will relock immediately
if (nSleepTime < 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Timeout cannot be negative.");
}
// Clamp timeout to 2^30 seconds
if (nSleepTime > (int64_t)1 << 30) {
nSleepTime = (int64_t)1 << 30;
}

if (strWalletPass.length() > 0)
{
if (!pwallet->Unlock(strWalletPass)) {
Expand All @@ -2311,7 +2323,6 @@ UniValue walletpassphrase(const JSONRPCRequest& request)

pwallet->TopUpKeyPool();

int64_t nSleepTime = request.params[1].get_int64();
pwallet->nRelockTime = GetTime() + nSleepTime;
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);

Expand Down

0 comments on commit 0b63e3c

Please sign in to comment.