BIO_dump_fp导致数百个valgrind错误

BIO_dump_fp causing hundreds of valgrind errors

本文关键字:百个 valgrind 错误 fp dump BIO      更新时间:2023-10-16

我正在尝试使用OpenSSL库进行AES加密。一切都很顺利。然而,当我使用BIO_dump_fp(stdout, (char*)ciphertext, ciphertext_len) valgrind时,最终报告了数百个错误,大多数是"移动的条件跳跃取决于未初始化的值"错误,比如下面的错误:

Conditional jump or move depends on uninitialised value(s)
    at 0x579A9C3: fwrite (iofwrite.c:49)
    by 0x4F187B0: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
    by 0x4F18AC4: BIO_dump_indent_cb (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
    by 0x401748: main (in /home/van/Desktop/aes-test/temp/test)

可以安全地忽略这些错误吗(即这些错误是假阳性吗)?如果重要的话,我使用的是Ubuntu 14.04,g++版本4.8.2,valgrind 3.10。

更新:我的完整源代码如下:

#include <stdio.h>
#include "QAesHelper.h"
int main(int argc, char *argv[])
{
  unsigned char iv[] = "1234567812345678";
  unsigned char key[] = "Testing Testing...";
  printf("Size of key: %dn", (int)sizeof(key));
  unsigned char plaintext[] = "The quick brown fox jumps over the lazy dog";
  int plaintext_len = sizeof(plaintext);
  printf("Size of plaintext: %dn", plaintext_len);
  unsigned char *ciphertext = (unsigned char*)malloc(plaintext_len + 32);
  unsigned char *decryptedtext = (unsigned char*)malloc(plaintext_len + 2);
  QAesHelper *aesHelper = new QAesHelper(key, sizeof(key));
  int ciphertext_len = aesHelper->encrypt(plaintext, plaintext_len, iv, sizeof(iv), &ciphertext);
  int decryptedtext_len = aesHelper->decrypt(ciphertext, ciphertext_len + 1, iv, sizeof(iv), &decryptedtext);
  // If I remove the following line (BIO_dump_fp...), then
  // valgrind reports no errors. With this line left in, there
  // are over 900 errors reported.
  BIO_dump_fp(stdout, (char*)ciphertext, ciphertext_len);
  delete aesHelper;
  free(ciphertext);
  free(decryptedtext);
  return 0;
}

而QAesHelper::encrypt()是:

int QAesHelper::encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *iv, int iv_len, unsigned char **ciphertext)
{
  EVP_CIPHER_CTX *ctx;
  int len;
  int ciphertext_len;
  if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
  if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
    handleErrors();
  if(1 != EVP_EncryptUpdate(ctx, *ciphertext, &len, plaintext, plaintext_len))
    handleErrors();
  ciphertext_len = len;
  if(1 != EVP_EncryptFinal_ex(ctx, *ciphertext + len, &len)) handleErrors();
  ciphertext_len += len;
  EVP_CIPHER_CTX_free(ctx);
  return ciphertext_len;
}

这不是一个错误。OpenSSL大量使用未初始化的内存段。Valgrind将这种用法视为错误并对此发出警告。它的正常行为可以在某种程度上美化:

  • 编写并使用valgrind抑制文件valgrind--gen抑制=no|yes|all
  • 在cflags中启用PURIFY宏的情况下编译openssl
  • 推送至valgrind--error limit=no并忽略来自libssl/libcrypto的警告