c++ - 这个 valgrind 在 crypto++ 中使用大小为 8 的未初始化值是真实的还是红鲱鱼?

标签 c++ valgrind crypto++

我有一个 valgrind 报告在库调用中 Use of uninitialised value of size 8 CryptoPP::HuffmanEncoder::GenerateCodeLengthsUbuntu 12.10 libcrypto++9_5.6.1-6_amd64.deb 上。

我需要进行完整性检查:应用程序代码有问题吗? (这是一个真正的可能性,因为我刚刚开始使用 crypto++。)还是我应该将 valgrind 警告抑制放入忽略过滤器中?

尽管有错误,但代码看起来可以正常工作。

make: `test3' is up to date.
==5420== Memcheck, a memory error detector
==5420== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5420== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5420== Command: ./test3
==5420== 
Plain text = 13312 bytes
==5420== Use of uninitialised value of size 8
==5420==    at 0x520D9A9: CryptoPP::HuffmanEncoder::GenerateCodeLengths(unsigned int*, unsigned int, unsigned int const*, unsigned long) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x520E0A5: CryptoPP::Deflator::EncodeBlock(bool, unsigned int) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x520EA2E: CryptoPP::Deflator::EndBlock(bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x520F221: CryptoPP::Deflator::Put2(unsigned char const*, unsigned long, int, bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x50F16DB: CryptoPP::BufferedTransformation::ChannelPut2(std::string const&, unsigned char const*, unsigned long, int, bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x50F1F76: CryptoPP::BufferedTransformation::TransferMessagesTo2(CryptoPP::BufferedTransformation&, unsigned int&, std::string const&, bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x50F2185: CryptoPP::BufferedTransformation::TransferAllTo2(CryptoPP::BufferedTransformation&, std::string const&, bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x4106A4: CryptoPP::StringSource::StringSource(std::string const&, bool, CryptoPP::BufferedTransformation*) (filters.h:767)
==5420==    by 0x40C7D5: main (test3.cpp:75)
==5420== 
==5420== Use of uninitialised value of size 8
==5420==    at 0x520D9A9: CryptoPP::HuffmanEncoder::GenerateCodeLengths(unsigned int*, unsigned int, unsigned int const*, unsigned long) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x520E0A5: CryptoPP::Deflator::EncodeBlock(bool, unsigned int) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x520EA4F: CryptoPP::Deflator::EndBlock(bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x520F221: CryptoPP::Deflator::Put2(unsigned char const*, unsigned long, int, bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x50F16DB: CryptoPP::BufferedTransformation::ChannelPut2(std::string const&, unsigned char const*, unsigned long, int, bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x50F1F76: CryptoPP::BufferedTransformation::TransferMessagesTo2(CryptoPP::BufferedTransformation&, unsigned int&, std::string const&, bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x50F2185: CryptoPP::BufferedTransformation::TransferAllTo2(CryptoPP::BufferedTransformation&, std::string const&, bool) (in /usr/lib/libcrypto++.so.9.0.0)
==5420==    by 0x4106A4: CryptoPP::StringSource::StringSource(std::string const&, bool, CryptoPP::BufferedTransformation*) (filters.h:767)
==5420==    by 0x40C7D5: main (test3.cpp:75)
==5420== 
Encrypted text = 110 bytes : JFuk7LvDTujLm3D8SdFZCwSXMQsslb0+AUf8sp53Z+oRDIp9aQY1azUF2PZZje/SV1q+IPz5
jGWYkJXlZv2ttADPUdMbg7ib+B4LGlb+7/k=
KEY[16]: ABD86728BB78D5722D07F247D8279CD9
IV [8]: BEBD442990B11C58
==5420== 
==5420== HEAP SUMMARY:
==5420==     in use at exit: 0 bytes in 0 blocks
==5420==   total heap usage: 118 allocs, 118 frees, 313,921 bytes allocated
==5420== 
==5420== All heap blocks were freed -- no leaks are possible
==5420== 
==5420== For counts of detected and suppressed errors, rerun with: -v
==5420== Use --track-origins=yes to see where uninitialised values come from
==5420== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)

编译

g++ -std=c++11 -g3 -O2 -Wall -Wextra -Wno-unused -o test3 test3.cpp -lrt -lcryptopp

test3.cpp代码

#include <cryptopp/blowfish.h>
#include <cryptopp/base64.h>
#include <cryptopp/files.h>
#include <cryptopp/filters.h>
#include <cryptopp/modes.h>
#include <cryptopp/gzip.h>
#include <cryptopp/osrng.h>
#include <cryptopp/hex.h>

#include <ctime>
#include <iostream>
#include <exception>

int main () 
{
    std::string plainText;
    timespec ts1, ts2;

    plainText = "Hello, world!";
    for (int i = 0; i < 10; i++) 
        plainText = plainText + plainText;

    byte   iv [ CryptoPP::Blowfish::BLOCKSIZE         ];
    byte   key[ CryptoPP::Blowfish::DEFAULT_KEYLENGTH ]; 

    const bool generate_fast = true;
    CryptoPP::AutoSeededRandomPool rng( !generate_fast ); 
    rng.GenerateBlock( iv,  sizeof( iv  ));
    rng.GenerateBlock( key, sizeof( key ));

    std::cout << "Plain text = " << plainText.size() << " bytes\n";

    std::string cipher, decipher;
    CryptoPP::StringSink*    sink       = new CryptoPP::StringSink( cipher  );
    CryptoPP::Base64Encoder* base64_enc = new CryptoPP::Base64Encoder( sink );
    CryptoPP::CBC_Mode<CryptoPP::Blowfish>::Encryption 
        twofish( key, CryptoPP::Blowfish::DEFAULT_KEYLENGTH, iv );
    CryptoPP::StreamTransformationFilter* 
        enc = new CryptoPP::StreamTransformationFilter( twofish, base64_enc );
    CryptoPP::Gzip *zip = new CryptoPP::Gzip( enc );
    CryptoPP::StringSource source( plainText, true, zip );
    std::cout << "Encrypted text = " << cipher.size() << " bytes : " << cipher;
}

最佳答案

根据 this当您使用尚未初始化的值(相当明显)时,valgrind 将报告一个未初始化的值。

就您的代码而言,不同的 C++ 编译器会根据传递的标志以不同方式处理已声明但未初始化的值。这可以是将它们设置为零,但不应假设。

valgrind 输出中的 8 个字节可能是一个指针,对这些使用未初始化的值尤其危险。

为了完全确定,您需要为此访问源代码,否则您总是会冒着未定义行为的风险。

关于c++ - 这个 valgrind 在 crypto++ 中使用大小为 8 的未初始化值是真实的还是红鲱鱼?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13762340/

相关文章:

c - 在 valgrind 中获取 "Syscall param execve(argv) points to unaddressable byte(s)"

c++ - 将十六进制字符串转换为 Crypto++ 中的字节

c++ - 为 Crypto++ 构建和链接测试代码

c++ - 使用 MFC 实现队列的正确方法?

c++ - std::condition_variable::wait with predicate

posix - 对于有缺陷、内存泄漏的 POSIX API,我们该怎么办?

c++ - RSA加密和解密期间的RandomNumberGenerator要求?

c++ - 使用 C++ 实时可视化图形的库

c++ - 有什么方法可以只内联一些对函数的选择性调用而不是全部?

linux - 如何在不重建的情况下在 Linux 平台上分析程序?