fixed segfault in bignum.h,
authors_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>
Sat, 31 Jul 2010 19:15:48 +0000 (19:15 +0000)
committers_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>
Sat, 31 Jul 2010 19:15:48 +0000 (19:15 +0000)
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

bignum.h
main.cpp
script.cpp
script.h
serialize.h
setup.nsi

index 44dfd97..0701f79 100644 (file)
--- a/bignum.h
+++ b/bignum.h
@@ -401,8 +401,16 @@ public:
 \r
     CBigNum& operator>>=(unsigned int shift)\r
     {\r
-        // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number,\r
-        //       tested OK on 64-bit ubuntu 10.4\r
+        // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number\r
+        //   if built on ubuntu 9.04 or 9.10, probably depends on version of openssl\r
+        CBigNum a = 1;\r
+        a <<= shift;\r
+        if (BN_cmp(&a, this) > 0)\r
+        {\r
+            *this = 0;\r
+            return *this;\r
+        }\r
+\r
         if (!BN_rshift(this, this, shift))\r
             throw bignum_error("CBigNum:operator>>= : BN_rshift failed");\r
         return *this;\r
@@ -511,10 +519,8 @@ inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
 \r
 inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)\r
 {\r
-    CBigNum r;\r
-    // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number\r
-    if (!BN_rshift(&r, &a, shift))\r
-        throw bignum_error("CBigNum:operator>> : BN_rshift failed");\r
+    CBigNum r = a;\r
+    r >>= shift;\r
     return r;\r
 }\r
 \r
index ddc359a..0239915 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -3036,7 +3036,8 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
                 foreach(CWalletTx* pcoin, setCoins)\r
                     for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)\r
                         if (pcoin->vout[nOut].IsMine())\r
-                            SignSignature(*pcoin, wtxNew, nIn++);\r
+                            if (!SignSignature(*pcoin, wtxNew, nIn++))\r
+                                return false;\r
 \r
                 // Check that enough fee is included\r
                 if (nFee < wtxNew.GetMinFee())\r
index 2b692ca..a88f915 100644 (file)
@@ -42,20 +42,17 @@ void MakeSameSize(valtype& vch1, valtype& vch2)
 #define stacktop(i)  (stack.at(stack.size()+(i)))\r
 #define altstacktop(i)  (altstack.at(altstack.size()+(i)))\r
 \r
-bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType,\r
-                vector<vector<unsigned char> >* pvStackRet)\r
+bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)\r
 {\r
     CAutoBN_CTX pctx;\r
     CScript::const_iterator pc = script.begin();\r
     CScript::const_iterator pend = script.end();\r
     CScript::const_iterator pbegincodehash = script.begin();\r
     vector<bool> vfExec;\r
-    vector<valtype> stack;\r
     vector<valtype> altstack;\r
-    if (pvStackRet)\r
-        pvStackRet->clear();\r
-    if (script.size() > 20000)\r
+    if (script.size() > 10000)\r
         return false;\r
+    int nOpCount = 0;\r
 \r
 \r
     try\r
@@ -73,6 +70,8 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
                 return false;\r
             if (vchPushValue.size() > 5000)\r
                 return false;\r
+            if (opcode > OP_16 && nOpCount++ > 200)\r
+                return false;\r
 \r
             if (fExec && opcode <= OP_PUSHDATA4)\r
                 stack.push_back(vchPushValue);\r
@@ -828,9 +827,7 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
     if (!vfExec.empty())\r
         return false;\r
 \r
-    if (pvStackRet)\r
-        *pvStackRet = stack;\r
-    return (stack.empty() ? false : CastToBool(stack.back()));\r
+    return true;\r
 }\r
 \r
 #undef top\r
@@ -1114,6 +1111,19 @@ bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret)
 }\r
 \r
 \r
+bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType)\r
+{\r
+    vector<vector<unsigned char> > stack;\r
+    if (!EvalScript(stack, scriptSig, txTo, nIn, nHashType))\r
+        return false;\r
+    if (!EvalScript(stack, scriptPubKey, txTo, nIn, nHashType))\r
+        return false;\r
+    if (stack.empty())\r
+        return false;\r
+    return CastToBool(stack.back());\r
+}\r
+\r
+\r
 bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)\r
 {\r
     assert(nIn < txTo.vin.size());\r
@@ -1132,7 +1142,7 @@ bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int
 \r
     // Test solution\r
     if (scriptPrereq.empty())\r
-        if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn))\r
+        if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, 0))\r
             return false;\r
 \r
     return true;\r
@@ -1150,7 +1160,7 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
     if (txin.prevout.hash != txFrom.GetHash())\r
         return false;\r
 \r
-    if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType))\r
+    if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, nHashType))\r
         return false;\r
 \r
     // Anytime a signature is successfully verified, it's proof the outpoint is spent,\r
index c5744d9..b32b5a1 100644 (file)
--- a/script.h
+++ b/script.h
@@ -657,8 +657,6 @@ public:
 \r
 \r
 \r
-bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0,\r
-                vector<vector<unsigned char> >* pvStackRet=NULL);\r
 uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);\r
 bool IsMine(const CScript& scriptPubKey);\r
 bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);\r
index 16804d4..8f3e060 100644 (file)
@@ -19,7 +19,7 @@ class CScript;
 class CDataStream;\r
 class CAutoFile;\r
 \r
-static const int VERSION = 306;\r
+static const int VERSION = 307;\r
 static const char* pszSubVer = "";\r
 \r
 \r
index a9b0b89..ea67778 100644 (file)
--- a/setup.nsi
+++ b/setup.nsi
@@ -7,7 +7,7 @@ RequestExecutionLevel highest
 \r
 # General Symbol Definitions\r
 !define REGKEY "SOFTWARE\$(^Name)"\r
-!define VERSION 0.3.6\r
+!define VERSION 0.3.7\r
 !define COMPANY "Bitcoin project"\r
 !define URL http://www.bitcoin.org/\r
 \r
@@ -42,12 +42,12 @@ Var StartMenuGroup
 !insertmacro MUI_LANGUAGE English\r
 \r
 # Installer attributes\r
-OutFile bitcoin-0.3.6-win32-setup.exe\r
+OutFile bitcoin-0.3.7-win32-setup.exe\r
 InstallDir $PROGRAMFILES\Bitcoin\r
 CRCCheck on\r
 XPStyle on\r
 ShowInstDetails show\r
-VIProductVersion 0.3.6.0\r
+VIProductVersion 0.3.7.0\r
 VIAddVersionKey ProductName Bitcoin\r
 VIAddVersionKey ProductVersion "${VERSION}"\r
 VIAddVersionKey CompanyName "${COMPANY}"\r