Clamp walletpassphrase timeout to 2^(30) seconds and check its bounds

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.
This commit is contained in:
Andrew Chow 2018-01-06 02:07:38 -05:00
parent 56910285fa
commit 0b63e3c7b2

View File

@ -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" "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"passphrase\" (string, required) The wallet passphrase\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" "\nNote:\n"
"Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n" "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
"time that overrides the old one.\n" "time that overrides the old one.\n"
@ -2298,6 +2299,17 @@ UniValue walletpassphrase(const JSONRPCRequest& request)
// Alternately, find a way to make request.params[0] mlock()'d to begin with. // Alternately, find a way to make request.params[0] mlock()'d to begin with.
strWalletPass = request.params[0].get_str().c_str(); 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 (strWalletPass.length() > 0)
{ {
if (!pwallet->Unlock(strWalletPass)) { if (!pwallet->Unlock(strWalletPass)) {
@ -2311,7 +2323,6 @@ UniValue walletpassphrase(const JSONRPCRequest& request)
pwallet->TopUpKeyPool(); pwallet->TopUpKeyPool();
int64_t nSleepTime = request.params[1].get_int64();
pwallet->nRelockTime = GetTime() + nSleepTime; pwallet->nRelockTime = GetTime() + nSleepTime;
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime); RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);