aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authors_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-07-31 19:15:48 +0000
committers_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-07-31 19:15:48 +0000
commit6ff5f718b6a67797b2b3bab8905d607ad216ee21 (patch)
treeeaa02182d314830966bcc8d0da8652c795570947
parent01bed1828b9ee64b9b38a7d0345c775de40fdd91 (diff)
fixed segfault in bignum.h,
additional security limits, refactoring -- version 0.3.7 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@121 1a98c847-1fd6-4fd8-948a-caf3550aa51b
-rw-r--r--bignum.h18
-rw-r--r--main.cpp3
-rw-r--r--script.cpp32
-rw-r--r--script.h2
-rw-r--r--serialize.h2
-rw-r--r--setup.nsi6
6 files changed, 39 insertions, 24 deletions
diff --git a/bignum.h b/bignum.h
index 44dfd97909..0701f7930f 100644
--- a/bignum.h
+++ b/bignum.h
@@ -401,8 +401,16 @@ public:
CBigNum& operator>>=(unsigned int shift)
{
- // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number,
- // tested OK on 64-bit ubuntu 10.4
+ // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
+ // if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
+ CBigNum a = 1;
+ a <<= shift;
+ if (BN_cmp(&a, this) > 0)
+ {
+ *this = 0;
+ return *this;
+ }
+
if (!BN_rshift(this, this, shift))
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
return *this;
@@ -511,10 +519,8 @@ inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
{
- CBigNum r;
- // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number
- if (!BN_rshift(&r, &a, shift))
- throw bignum_error("CBigNum:operator>> : BN_rshift failed");
+ CBigNum r = a;
+ r >>= shift;
return r;
}
diff --git a/main.cpp b/main.cpp
index ddc359af80..0239915c4a 100644
--- a/main.cpp
+++ b/main.cpp
@@ -3036,7 +3036,8 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
foreach(CWalletTx* pcoin, setCoins)
for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
if (pcoin->vout[nOut].IsMine())
- SignSignature(*pcoin, wtxNew, nIn++);
+ if (!SignSignature(*pcoin, wtxNew, nIn++))
+ return false;
// Check that enough fee is included
if (nFee < wtxNew.GetMinFee())
diff --git a/script.cpp b/script.cpp
index 2b692caf42..a88f915900 100644
--- a/script.cpp
+++ b/script.cpp
@@ -42,20 +42,17 @@ void MakeSameSize(valtype& vch1, valtype& vch2)
#define stacktop(i) (stack.at(stack.size()+(i)))
#define altstacktop(i) (altstack.at(altstack.size()+(i)))
-bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType,
- vector<vector<unsigned char> >* pvStackRet)
+bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
CAutoBN_CTX pctx;
CScript::const_iterator pc = script.begin();
CScript::const_iterator pend = script.end();
CScript::const_iterator pbegincodehash = script.begin();
vector<bool> vfExec;
- vector<valtype> stack;
vector<valtype> altstack;
- if (pvStackRet)
- pvStackRet->clear();
- if (script.size() > 20000)
+ if (script.size() > 10000)
return false;
+ int nOpCount = 0;
try
@@ -73,6 +70,8 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
return false;
if (vchPushValue.size() > 5000)
return false;
+ if (opcode > OP_16 && nOpCount++ > 200)
+ return false;
if (fExec && opcode <= OP_PUSHDATA4)
stack.push_back(vchPushValue);
@@ -828,9 +827,7 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
if (!vfExec.empty())
return false;
- if (pvStackRet)
- *pvStackRet = stack;
- return (stack.empty() ? false : CastToBool(stack.back()));
+ return true;
}
#undef top
@@ -1114,6 +1111,19 @@ bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret)
}
+bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType)
+{
+ vector<vector<unsigned char> > stack;
+ if (!EvalScript(stack, scriptSig, txTo, nIn, nHashType))
+ return false;
+ if (!EvalScript(stack, scriptPubKey, txTo, nIn, nHashType))
+ return false;
+ if (stack.empty())
+ return false;
+ return CastToBool(stack.back());
+}
+
+
bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
{
assert(nIn < txTo.vin.size());
@@ -1132,7 +1142,7 @@ bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int
// Test solution
if (scriptPrereq.empty())
- if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn))
+ if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, 0))
return false;
return true;
@@ -1150,7 +1160,7 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
if (txin.prevout.hash != txFrom.GetHash())
return false;
- if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType))
+ if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, nHashType))
return false;
// Anytime a signature is successfully verified, it's proof the outpoint is spent,
diff --git a/script.h b/script.h
index c5744d9f3f..b32b5a19f5 100644
--- a/script.h
+++ b/script.h
@@ -657,8 +657,6 @@ public:
-bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0,
- vector<vector<unsigned char> >* pvStackRet=NULL);
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
bool IsMine(const CScript& scriptPubKey);
bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);
diff --git a/serialize.h b/serialize.h
index 16804d4e91..8f3e0601e3 100644
--- a/serialize.h
+++ b/serialize.h
@@ -19,7 +19,7 @@ class CScript;
class CDataStream;
class CAutoFile;
-static const int VERSION = 306;
+static const int VERSION = 307;
static const char* pszSubVer = "";
diff --git a/setup.nsi b/setup.nsi
index a9b0b89526..ea67778fa7 100644
--- a/setup.nsi
+++ b/setup.nsi
@@ -7,7 +7,7 @@ RequestExecutionLevel highest
# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
-!define VERSION 0.3.6
+!define VERSION 0.3.7
!define COMPANY "Bitcoin project"
!define URL http://www.bitcoin.org/
@@ -42,12 +42,12 @@ Var StartMenuGroup
!insertmacro MUI_LANGUAGE English
# Installer attributes
-OutFile bitcoin-0.3.6-win32-setup.exe
+OutFile bitcoin-0.3.7-win32-setup.exe
InstallDir $PROGRAMFILES\Bitcoin
CRCCheck on
XPStyle on
ShowInstDetails show
-VIProductVersion 0.3.6.0
+VIProductVersion 0.3.7.0
VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"