风险提示:理性看待区块链,提高风险意识!
给比特币做一次体检
首页 > 币界资讯 > 区块链知识 2014-08-07 16:07:00

不要指望这是一篇多么史诗的文章,这里只是用PVS-Studio检查了下比特币项目的源代码,并发现了其中一些可疑的片段。我想已经有很多程序员已经检查过比特币源代码了吧,不过既然我们也做了一次检查,这里就简单地说明下。

image1

首先我们决定用PVS-Studio以及Clang进行对比测试,这是一个庞大而复杂的任务,我并不认为它能够很快完成。下面是这项任务中遇到的几个难题:

我们需要收集的项目是由GCC建立,但也可以由Clang进行编译。如果我们直接用Clang检查这些项目,Clang是不会发现漏洞的,因为在Clang的帮助下这些漏洞已经被修复了。但是PVS-Studio就可以。

一般来说,几乎没有项目可以同时在Clang以及Visual Studio上进行编译,Clang号称能够很好地兼容Visual Studio,但实际操作中却是另一码事,很多项目都不能正常建立和检查。而PVS-Studio在Linux平台下运行的情况却又是不如人意,因此我们所寻找的项目需要在这两种工具上都可以很好的进行处理。

比特币就是我们所选择的对比项目之一,两种工具运行完后所发现的错误也几乎为零,这也无需奇怪 —— 我想这个项目早就被检查烂了,这也就是为什么我们将大部分比较从中排除的原因,下面我们就简单地概括下这次检查。

项目分析

我想比特币是什么这里也就没必要进行介绍了,都快被玩坏了,源代码从这里下载: https://github.com/bitcoin/bitcoin

本次分析通过5.17版本PVS-Studio完成。

奇怪的循环

下面是该检测分析唯一我觉得可疑的片段。这是一段和密码学相关的函数,我不知道它到底有何作用,或许我找到了惊天秘密也说不定呢,现在这个年代,程序猿最乐意做的事就是发现一些关于安全性的大BUG,你懂的。但是,这里可能只是一个小错误,甚至是一段故意编写的代码。

bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
{
 {
  LOCK(cs_KeyStore);
  if (!SetCrypted())
  return false;

  CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
  for (; mi != mapCryptedKeys.end(); ++mi)
  {
    const CPubKey &vchPubKey = (*mi).second.first;
    const std::vector<unsigned char> &vchCryptedSecret =
    (*mi).second.second;
    CKeyingMaterial vchSecret;
    if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret,
                    vchPubKey.GetHash(), vchSecret))
      return false;
    if (vchSecret.size() != 32)
      return false;
    CKey key;
    key.Set(vchSecret.begin(), vchSecret.end(),
          vchPubKey.IsCompressed());
    if (key.GetPubKey() == vchPubKey)
      break;
    return false;
  }
  vMasterKey = vMasterKeyIn;
}
NotifyStatusChanged(this);
return true;
}

注意这个循环,它必须遍历某些键值,然而,其循环体只执行一次。还有就是在该循环结束时,会有一个“return false;”操作,它也可以由“break;”终止,与此同时,并不存在一个单一的“continue;”的操作。

可疑的转变

static int64_t set_vch(const std::vector<unsigned char>& vch)
{
  if (vch.empty())
    return 0;

  int64_t result = 0;
  for (size_t i = 0; i != vch.size(); ++i)
      result |= static_cast<int64_t>(vch[i]) << 8*i;

  // If the input vector's most significant byte is 0x80,
  // remove it from the result's msb and return a negative.
  if (vch.back() & 0x80)
      return -(result & ~(0x80 << (8 * (vch.size() - 1))));

   return result;
 }

PVS-Studio的诊断信息:V629 检查了 ’0×80 << (8 * (vch.size() – 1))’语句,Bit从32位值扩展到64位值, script.h 169。

该功能形成了一个64位的值,其中一个转变是正确的,其他的可能不是。

正确的行:

 static_cast<int64_t>(vch[i]) << 8*i

变量首先延伸到int64_t ,然后进行转移

可疑行:

 0x80 << (8 * (vch.size() - 1))

该0×80的常数是’整数’类型,这意味着移动它可能会导致溢出。由于该函数生成了一个64位的值,我怀疑这里是有一个错误的。如果要了解更多关于准换的信息,可以参见,“Wade not in unknown waters – part three”这篇文章。

不变的代码:

 0x80ull << (8 * (vch.size() - 1))

危险类

class CKey {
  ....
  // Copy constructor. This is necessary because of memlocking.
  CKey(const CKey &secret) : fValid(secret.fValid),
                         fCompressed(secret.fCompressed) {
    LockObject(vch);
    memcpy(vch, secret.vch, sizeof(vch));
  }
  ....
};

PVS-Studio的诊断信息:V690中的’CKey’类实现了一个拷贝构造函数,但它缺少“=”操作符。使用这样的类是危险的。key.h 175

很多人认为拷贝构造函数是对于同步来说必须的,然而,一个项目不应该只通过拷贝构造函数来进行复制,“=”操作在这段代码中并未出现,尽管目前看来=操作还未能派上用场,但是这段代码还是有潜在危险的。

同样的,还有一些需要进行仔细检查的类:

V690 “Semantic_actions”类实现了’='操作,但缺少一个拷贝构造函数,使用这样的类是危险的。json_spirit_reader_template.h196

V690 “CFeeRate”类实现一个拷贝构造函数,但缺少“=”操作符,使用这样的类是危险的。 core.h118

V690 “CTransaction”类实现了’='操作,但缺少一个拷贝构造函数,使用这样的类是危险的。core.h212

V690 “CTxMemPoolEntry”类实现一个拷贝构造函数,但缺少“=”操作符,使用这样的类是危险的。txmempool.h27

V690 “Json_grammer”类实现了’='操作,但缺少一个拷贝构造函数,使用这样的类是危险的。 json_spirit_reader_template.h370

V690 ‘Generator’类实现了’='操作,但缺少一个拷贝构造函数,使用这样的类是危险的。 json_spirit_writer_template.h98

结论

定期使用静态分析器可以帮助你节省大量的时间和神经细胞,最主要的是,它很方便,哈哈,比特币君挺住啊,别被玩坏咯。

原文:http://www.viva64.com/en/b/0268/?utm_source=bitcoinweekly&utm_medium=email#ID0EKWBI

作者:Andrey Karpov

翻译:小蒙牛

上一篇: 比特币地址生成(图形化)
下一篇: 搞清楚Blockchain的安全,只需要一点技术!
推荐专栏
web3首席知识博主
一位相信价值投资的币圈KOL。稳定盈利的缠论野生交易员 #BTC行情分析师 #价值投资 #链上数据分析
爱Web 3,爱生活,爱科技,爱炒币的老韭菜
热门币种
更多
币种
价格
24H涨跌幅
BTC比特币
¥264,810.46
37,103.37 USDT
+0.1%
ETH以太坊
¥14,413.37
2,019.50 USDT
0%
USDT泰达币
¥7.20
1.01 USDT
0%
BNB币安币
¥1,629.54
228.32 USDT
+0.63%
XRP瑞波币
¥4.32
0.60480 USDT
+0.45%
USDC
¥7.14
1.00 USDT
+0.04%
SOLSolana
¥400.45
56.11 USDT
+1.59%
OKBOK币
¥399.37
55.96 USDT
-1.23%
ADA艾达币
¥2.67
0.37480 USDT
-1.32%
DOGE狗狗币
¥0.55330
0.07753 USDT
-1.01%
热搜币种
更多
币种
价格
24H涨跌幅
Terra Classic
¥0.00
9.481E-5 USDT
-18.15%
Gala
¥0.18
0.025383 USDT
-4.86%
dYdX
¥22.63
3.1984 USDT
-0.73%
比特股
¥0.05
0.006569 USDT
-1.93%
PancakeSwap
¥15.60
2.2054 USDT
-2.16%
Conflux
¥1.08
0.1531 USDT
-2.36%
Filecoin
¥31.55
4.4597 USDT
-0.5%
FTX Token
¥29.65
4.1911 USDT
+15.24%
Yield Guild Games
¥2.56
0.3615 USDT
-0.55%
Shiba Inu
¥0.00
8.15E-6 USDT
-2.16%
比特币
¥262,467.38
37103.37 USDT
+0.1%
比原链
¥0.07
0.010022 USDT
-4.68%
最新快讯
更多
汇丰、恒生、渣打、富邦华一四家外资银行入围首批“数字人民币”业务试点名单
2023-11-28 19:06:57
摩根大通和Apollo计划建立代币化“企业主网”
2023-11-28 19:03:57
Nansen2公测版本上线,新增链上数据异动、智能搜索等功能
2023-11-28 18:59:52
西班牙公民需在明年3月底前申报其海外平台上加密货币持仓
2023-11-28 18:53:43
Nansen2已公开测试
2023-11-28 18:53:38
dYdX基金会:主网启动以来超过1645万DYDX被质押
2023-11-28 18:52:07
NicCarter等比特币倡导者发文:比特币挖矿是清洁能源和平衡电网的关键工具
2023-11-28 18:47:58
下载币界网APP