Skip to content

Commit 6ff5f71

Browse files
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
1 parent 01bed18 commit 6ff5f71

File tree

6 files changed

+39
-24
lines changed

6 files changed

+39
-24
lines changed

bignum.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,16 @@ class CBigNum : public BIGNUM
401401

402402
CBigNum& operator>>=(unsigned int shift)
403403
{
404-
// Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number,
405-
// tested OK on 64-bit ubuntu 10.4
404+
// Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
405+
// if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
406+
CBigNum a = 1;
407+
a <<= shift;
408+
if (BN_cmp(&a, this) > 0)
409+
{
410+
*this = 0;
411+
return *this;
412+
}
413+
406414
if (!BN_rshift(this, this, shift))
407415
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
408416
return *this;
@@ -511,10 +519,8 @@ inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
511519

512520
inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
513521
{
514-
CBigNum r;
515-
// Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number
516-
if (!BN_rshift(&r, &a, shift))
517-
throw bignum_error("CBigNum:operator>> : BN_rshift failed");
522+
CBigNum r = a;
523+
r >>= shift;
518524
return r;
519525
}
520526

main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3036,7 +3036,8 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
30363036
foreach(CWalletTx* pcoin, setCoins)
30373037
for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
30383038
if (pcoin->vout[nOut].IsMine())
3039-
SignSignature(*pcoin, wtxNew, nIn++);
3039+
if (!SignSignature(*pcoin, wtxNew, nIn++))
3040+
return false;
30403041

30413042
// Check that enough fee is included
30423043
if (nFee < wtxNew.GetMinFee())

script.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,17 @@ void MakeSameSize(valtype& vch1, valtype& vch2)
4242
#define stacktop(i) (stack.at(stack.size()+(i)))
4343
#define altstacktop(i) (altstack.at(altstack.size()+(i)))
4444

45-
bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType,
46-
vector<vector<unsigned char> >* pvStackRet)
45+
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
4746
{
4847
CAutoBN_CTX pctx;
4948
CScript::const_iterator pc = script.begin();
5049
CScript::const_iterator pend = script.end();
5150
CScript::const_iterator pbegincodehash = script.begin();
5251
vector<bool> vfExec;
53-
vector<valtype> stack;
5452
vector<valtype> altstack;
55-
if (pvStackRet)
56-
pvStackRet->clear();
57-
if (script.size() > 20000)
53+
if (script.size() > 10000)
5854
return false;
55+
int nOpCount = 0;
5956

6057

6158
try
@@ -73,6 +70,8 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
7370
return false;
7471
if (vchPushValue.size() > 5000)
7572
return false;
73+
if (opcode > OP_16 && nOpCount++ > 200)
74+
return false;
7675

7776
if (fExec && opcode <= OP_PUSHDATA4)
7877
stack.push_back(vchPushValue);
@@ -828,9 +827,7 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
828827
if (!vfExec.empty())
829828
return false;
830829

831-
if (pvStackRet)
832-
*pvStackRet = stack;
833-
return (stack.empty() ? false : CastToBool(stack.back()));
830+
return true;
834831
}
835832

836833
#undef top
@@ -1114,6 +1111,19 @@ bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret)
11141111
}
11151112

11161113

1114+
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType)
1115+
{
1116+
vector<vector<unsigned char> > stack;
1117+
if (!EvalScript(stack, scriptSig, txTo, nIn, nHashType))
1118+
return false;
1119+
if (!EvalScript(stack, scriptPubKey, txTo, nIn, nHashType))
1120+
return false;
1121+
if (stack.empty())
1122+
return false;
1123+
return CastToBool(stack.back());
1124+
}
1125+
1126+
11171127
bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
11181128
{
11191129
assert(nIn < txTo.vin.size());
@@ -1132,7 +1142,7 @@ bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int
11321142

11331143
// Test solution
11341144
if (scriptPrereq.empty())
1135-
if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn))
1145+
if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, 0))
11361146
return false;
11371147

11381148
return true;
@@ -1150,7 +1160,7 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
11501160
if (txin.prevout.hash != txFrom.GetHash())
11511161
return false;
11521162

1153-
if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType))
1163+
if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, nHashType))
11541164
return false;
11551165

11561166
// Anytime a signature is successfully verified, it's proof the outpoint is spent,

script.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,6 @@ class CScript : public vector<unsigned char>
657657

658658

659659

660-
bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0,
661-
vector<vector<unsigned char> >* pvStackRet=NULL);
662660
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
663661
bool IsMine(const CScript& scriptPubKey);
664662
bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);

serialize.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class CScript;
1919
class CDataStream;
2020
class CAutoFile;
2121

22-
static const int VERSION = 306;
22+
static const int VERSION = 307;
2323
static const char* pszSubVer = "";
2424

2525

setup.nsi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ RequestExecutionLevel highest
77

88
# General Symbol Definitions
99
!define REGKEY "SOFTWARE\$(^Name)"
10-
!define VERSION 0.3.6
10+
!define VERSION 0.3.7
1111
!define COMPANY "Bitcoin project"
1212
!define URL http://www.bitcoin.org/
1313

@@ -42,12 +42,12 @@ Var StartMenuGroup
4242
!insertmacro MUI_LANGUAGE English
4343

4444
# Installer attributes
45-
OutFile bitcoin-0.3.6-win32-setup.exe
45+
OutFile bitcoin-0.3.7-win32-setup.exe
4646
InstallDir $PROGRAMFILES\Bitcoin
4747
CRCCheck on
4848
XPStyle on
4949
ShowInstDetails show
50-
VIProductVersion 0.3.6.0
50+
VIProductVersion 0.3.7.0
5151
VIAddVersionKey ProductName Bitcoin
5252
VIAddVersionKey ProductVersion "${VERSION}"
5353
VIAddVersionKey CompanyName "${COMPANY}"

0 commit comments

Comments
 (0)