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 unsigned char* key_;
char init_vector_[kBlockSize];
EVP_CIPHER_CTX* ctx_;
Status handleErrors(const char * str);
};
@ -108,24 +107,25 @@ class OpensslCipherStream : public BlockAccessCipherStream {
OpensslCipherStream::OpensslCipherStream(const EVP_CIPHER *aes_cipher,
const unsigned char* key,
const char* init_vector)
: aes_cipher_(aes_cipher), key_(key), ctx_(nullptr) {
: aes_cipher_(aes_cipher), key_(key) {
memcpy(init_vector_,init_vector,kBlockSize);
ctx_ = EVP_CIPHER_CTX_new();
//ctx_ = EVP_CIPHER_CTX_new();
}
OpensslCipherStream::~OpensslCipherStream() {
//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) {
# ifndef OPENSSL_NO_STDIO
ERR_print_errors_fp(stderr);
# endif
if (ctx_ != nullptr) {
EVP_CIPHER_CTX_free(ctx_);
ctx_ = nullptr;
}
// if (ctx_ != nullptr) {
// EVP_CIPHER_CTX_free(ctx_);
// ctx_ = nullptr;
// }
return Status::Aborted(str);
}
@ -143,7 +143,10 @@ Status OpensslCipherStream::Encrypt(uint64_t fileOffset, char* data,
size_t dataSize) {
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 offset = fileOffset % kBlockSize;
@ -184,12 +187,12 @@ Status OpensslCipherStream::Encrypt(uint64_t fileOffset, char* data,
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);
if (offset == 0) {
//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);
//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_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;
size_t n = std::min(kBlockSize - offset, dataSize);
@ -208,7 +211,7 @@ Status OpensslCipherStream::Encrypt(uint64_t fileOffset, char* data,
if (dataSize > n) {
char* ptr = (char*)(data + 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);
//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);
}
if (ctx_ != nullptr) EVP_CIPHER_CTX_free(ctx_);
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,

@ -1,6 +1,6 @@
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
all: ippcp_example

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

Loading…
Cancel
Save