fix intermittent segfault discovered in test in openbsd. new ctx for every encrypt

oxigraph-main
Niko PLP 1 year ago
parent 56e77c4c66
commit d334e861a1
  1. 38
      plugin/openssl/openssl_provider.cc
  2. 2
      plugin/openssl/test_openssl/Makefile
  3. 23
      plugin/openssl/test_openssl/ippcp_example.cc

@ -100,7 +100,6 @@ class OpensslCipherStream : public BlockAccessCipherStream {
const EVP_CIPHER *aes_cipher_; const EVP_CIPHER *aes_cipher_;
const unsigned char* key_; const unsigned char* key_;
char init_vector_[kBlockSize]; char init_vector_[kBlockSize];
EVP_CIPHER_CTX* ctx_;
Status handleErrors(const char * str); Status handleErrors(const char * str);
}; };
@ -108,24 +107,25 @@ class OpensslCipherStream : public BlockAccessCipherStream {
OpensslCipherStream::OpensslCipherStream(const EVP_CIPHER *aes_cipher, OpensslCipherStream::OpensslCipherStream(const EVP_CIPHER *aes_cipher,
const unsigned char* key, const unsigned char* key,
const char* init_vector) const char* init_vector)
: aes_cipher_(aes_cipher), key_(key), ctx_(nullptr) { : aes_cipher_(aes_cipher), key_(key) {
memcpy(init_vector_,init_vector,kBlockSize); memcpy(init_vector_,init_vector,kBlockSize);
ctx_ = EVP_CIPHER_CTX_new(); //ctx_ = EVP_CIPHER_CTX_new();
} }
OpensslCipherStream::~OpensslCipherStream() { OpensslCipherStream::~OpensslCipherStream() {
//EVP_CIPHER_free(aes_cipher_); //EVP_CIPHER_free(aes_cipher_);
if (ctx_ != nullptr) EVP_CIPHER_CTX_free(ctx_); //if (ctx_ != nullptr) EVP_CIPHER_CTX_free(ctx_);
} }
Status OpensslCipherStream::handleErrors(const char * str) { Status OpensslCipherStream::handleErrors(const char * str) {
# ifndef OPENSSL_NO_STDIO # ifndef OPENSSL_NO_STDIO
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
# endif # endif
if (ctx_ != nullptr) {
EVP_CIPHER_CTX_free(ctx_); // if (ctx_ != nullptr) {
ctx_ = nullptr; // EVP_CIPHER_CTX_free(ctx_);
} // ctx_ = nullptr;
// }
return Status::Aborted(str); return Status::Aborted(str);
} }
@ -143,7 +143,10 @@ Status OpensslCipherStream::Encrypt(uint64_t fileOffset, char* data,
size_t dataSize) { size_t dataSize) {
if (dataSize == 0) return Status::OK(); if (dataSize == 0) return Status::OK();
if ( 1 != EVP_CIPHER_CTX_reset(ctx_)) { return handleErrors("Failed to reset context."); } const char * err_str = nullptr;
EVP_CIPHER_CTX* ctx_ = EVP_CIPHER_CTX_new();
// if ( 1 != EVP_CIPHER_CTX_reset(ctx_)) { err_str="Failed to reset context."; goto error; }
size_t index = fileOffset / kBlockSize; size_t index = fileOffset / kBlockSize;
size_t offset = fileOffset % kBlockSize; size_t offset = fileOffset % kBlockSize;
@ -184,12 +187,12 @@ Status OpensslCipherStream::Encrypt(uint64_t fileOffset, char* data,
int len; int len;
if( 1 != EVP_EncryptInit_ex(ctx_, aes_cipher_, NULL, key_, ctr_block)) return handleErrors("Failed to init cipher."); if( 1 != EVP_EncryptInit_ex(ctx_, aes_cipher_, NULL, key_, ctr_block)) {err_str="Failed to init cipher."; goto error;}
EVP_CIPHER_CTX_set_padding(ctx_, 0); EVP_CIPHER_CTX_set_padding(ctx_, 0);
if (offset == 0) { if (offset == 0) {
//unsigned char *out = (unsigned char*)malloc(dataSize); //unsigned char *out = (unsigned char*)malloc(dataSize);
if( 1 != EVP_EncryptUpdate(ctx_, reinterpret_cast<unsigned char *>(data), &len, reinterpret_cast<const unsigned char *>(data), static_cast<int>(dataSize))) return handleErrors("Failed to encrypt."); if( 1 != EVP_EncryptUpdate(ctx_, reinterpret_cast<unsigned char *>(data), &len, reinterpret_cast<const unsigned char *>(data), static_cast<int>(dataSize))) {err_str="Failed to encrypt."; goto error;}
//memcpy(data, out, dataSize); //memcpy(data, out, dataSize);
//EVP_EncryptFinal_ex(ctx_, reinterpret_cast<unsigned char *>(data) + len, &len); //EVP_EncryptFinal_ex(ctx_, reinterpret_cast<unsigned char *>(data) + len, &len);
@ -197,7 +200,7 @@ Status OpensslCipherStream::Encrypt(uint64_t fileOffset, char* data,
unsigned char zero_block[kBlockSize]{0}; unsigned char zero_block[kBlockSize]{0};
//unsigned char zero_block_out[kBlockSize]{0}; //unsigned char zero_block_out[kBlockSize]{0};
if( 1 != EVP_EncryptUpdate(ctx_, zero_block, &len, zero_block, static_cast<int>(kBlockSize))) return handleErrors("Failed to encrypt zero block."); if( 1 != EVP_EncryptUpdate(ctx_, zero_block, &len, zero_block, static_cast<int>(kBlockSize))) {err_str="Failed to encrypt zero block."; goto error;}
//unsigned char * end = reinterpret_cast<unsigned char *>(zero_block) + len; //unsigned char * end = reinterpret_cast<unsigned char *>(zero_block) + len;
size_t n = std::min(kBlockSize - offset, dataSize); size_t n = std::min(kBlockSize - offset, dataSize);
@ -208,7 +211,7 @@ Status OpensslCipherStream::Encrypt(uint64_t fileOffset, char* data,
if (dataSize > n) { if (dataSize > n) {
char* ptr = (char*)(data + n); char* ptr = (char*)(data + n);
//unsigned char *out = (unsigned char*)malloc(dataSize - n); //unsigned char *out = (unsigned char*)malloc(dataSize - n);
if( 1 != EVP_EncryptUpdate(ctx_, reinterpret_cast<unsigned char *>(ptr), &len, reinterpret_cast<const unsigned char *>(ptr), static_cast<int>(dataSize - n))) return handleErrors("Failed to encrypt remaining."); if( 1 != EVP_EncryptUpdate(ctx_, reinterpret_cast<unsigned char *>(ptr), &len, reinterpret_cast<const unsigned char *>(ptr), static_cast<int>(dataSize - n))) {err_str="Failed to encrypt remaining."; goto error;}
//memcpy(ptr, out, dataSize - n); //memcpy(ptr, out, dataSize - n);
//end = reinterpret_cast<unsigned char *>(ptr) + len; //end = reinterpret_cast<unsigned char *>(ptr) + len;
} }
@ -216,7 +219,16 @@ Status OpensslCipherStream::Encrypt(uint64_t fileOffset, char* data,
//EVP_EncryptFinal_ex(ctx_, end, &len); //EVP_EncryptFinal_ex(ctx_, end, &len);
} }
if (ctx_ != nullptr) EVP_CIPHER_CTX_free(ctx_);
return Status::OK(); return Status::OK();
error:
if (ctx_ != nullptr) EVP_CIPHER_CTX_free(ctx_);
ERR_print_errors_fp(stderr);
if (err_str != nullptr) return Status::Aborted(err_str);
else return Status::Aborted("unknown error");
} }
Status OpensslCipherStream::Decrypt(uint64_t fileOffset, char* data, Status OpensslCipherStream::Decrypt(uint64_t fileOffset, char* data,

@ -1,6 +1,6 @@
include ../../../make_config.mk include ../../../make_config.mk
PLATFORM_LDFLAGS += -lrocksdb -lcrypto -L../../.. -L../../../../rust-rocksdb/target/debug/build/openssl-sys-019f70ebcbe84526/out/openssl-build/install/lib/ PLATFORM_LDFLAGS += -lrocksdb -lcrypto -L../../..
.PHONY: clean .PHONY: clean
all: ippcp_example all: ippcp_example

@ -21,12 +21,12 @@ std::string kDBPath = "/tmp/oss_aes_example";
int main() { int main() {
std::unique_ptr<EncryptionProvider> provider = OpensslProvider::CreateProvider(); //std::unique_ptr<EncryptionProvider> provider = OpensslProvider::CreateProvider();
provider->AddCipher("", "a6d2ae2816157e2b3c4fcf098815f7xb", 32, false); //provider->AddCipher("", "a6d2ae2816157e2b3c4fcf098815f7xb", 32, false);
char prefixb[4096]; //char prefixb[4096];
Slice ps = Slice(prefixb, 4096); //Slice ps = Slice(prefixb, 4096);
provider->CreateNewPrefix("",prefixb,4096); //provider->CreateNewPrefix("",prefixb,4096);
Status s; //Status s;
// const EnvOptions envoptions; // const EnvOptions envoptions;
// std::unique_ptr<BlockAccessCipherStream> s; // std::unique_ptr<BlockAccessCipherStream> s;
// provider->CreateCipherStream("",envoptions,ps,&s); // provider->CreateCipherStream("",envoptions,ps,&s);
@ -210,8 +210,9 @@ int main() {
setbuf(stdout, NULL); setbuf(stdout, NULL);
printf("writing 1M records..."); printf("writing 1M records...");
WriteOptions w_opts; WriteOptions w_opts;
for (int i = 0; i < 1000000; ++i) { int offset = 0;
status = db->Put(w_opts, std::to_string(i), std::to_string(i * i)); for (int i = offset+0; i < 1000000+offset; ++i) {
status = db->Put(w_opts, std::to_string(i), std::to_string(i ));
assert(status.ok()); assert(status.ok());
} }
db->Flush(FlushOptions()); db->Flush(FlushOptions());
@ -223,15 +224,15 @@ int main() {
for (int i = 0; i < 1000000; ++i) { for (int i = 0; i < 1000000; ++i) {
status = db->Get(r_opts, std::to_string(i), &value); status = db->Get(r_opts, std::to_string(i), &value);
assert(status.ok()); assert(status.ok());
assert(value == std::to_string(i * i)); assert(value == std::to_string(i ));
} }
printf("done.\n"); printf("done.\n");
// Close database // Close database
status = db->Close(); status = db->Close();
assert(status.ok()); assert(status.ok());
status = DestroyDB(kDBPath, dboptions); //status = DestroyDB(kDBPath, dboptions);
assert(status.ok()); //assert(status.ok());
return 0; return 0;
} }

Loading…
Cancel
Save