Skip to content

Commit 0bea175

Browse files
committed
fix: use proper return value check for EVP_CIPHER_CTX_ctrl()
This function can theoretically return -1, which would then be converted to a truthy value. If this happens, then this can cause issues at the use sites. E.g. for the test-crypto-cipheriv-decipheriv test in Node this can cause a buffer overflow when we test with an injected error: ``` ==714700==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000032b98 READ of size 12 at 0x502000032b98 thread T0 #0 0x558a7790bb97 in memcpy (/work/node/out/Debug/node+0x1b0bb97) #1 0x7efe5386f90b (/lib/x86_64-linux-gnu/libcrypto.so.3+0x45f90b) #2 0x7efe536312c2 in EVP_CipherInit_ex (/lib/x86_64-linux-gnu/libcrypto.so.3+0x2212c2) #3 0x558a7d3e7785 in ncrypto::CipherCtxPointer::init /work/node/out/../deps/ncrypto/ncrypto.cc:3328:10 #4 0x558a78512a1b in node::crypto::CipherBase::CommonInit /work/node/out/../src/crypto/crypto_cipher.cc:366:13 #5 0x558a785125dd in node::crypto::CipherBase::InitIv /work/node/out/../src/crypto/crypto_cipher.cc:409:3 #6 0x558a7850f5f4 in node::crypto::CipherBase::New /work/node/out/../src/crypto/crypto_cipher.cc:328:11 #7 0x558a788ee605 in v8::internal::FunctionCallbackArguments::CallOrConstruct /work/node/out/../deps/v8/src/api/api-arguments-inl.h:93:3 #8 0x558a788ec3ba in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<true> /work/node/out/../deps/v8/src/builtins/builtins-api.cc:104:16 #9 0x558a788e91fc in v8::internal::Builtin_Impl_HandleApiConstruct /work/node/out/../deps/v8/src/builtins/builtins-api.cc:135:3 #10 0x558a788e91fc in v8::internal::Builtin_HandleApiConstruct /work/node/out/../deps/v8/src/builtins/builtins-api.cc:126:1 #11 0x7efe31a951b5 (<unknown module>) ```
1 parent 630ee8b commit 0bea175

1 file changed

Lines changed: 7 additions & 5 deletions

File tree

src/ncrypto.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3403,19 +3403,21 @@ bool CipherCtxPointer::setKeyLength(size_t length) {
34033403
bool CipherCtxPointer::setIvLength(size_t length) {
34043404
if (!ctx_) return false;
34053405
return EVP_CIPHER_CTX_ctrl(
3406-
ctx_.get(), EVP_CTRL_AEAD_SET_IVLEN, length, nullptr);
3406+
ctx_.get(), EVP_CTRL_AEAD_SET_IVLEN, length, nullptr) > 0;
34073407
}
34083408

34093409
bool CipherCtxPointer::setAeadTag(const Buffer<const char>& tag) {
34103410
if (!ctx_) return false;
3411-
return EVP_CIPHER_CTX_ctrl(
3412-
ctx_.get(), EVP_CTRL_AEAD_SET_TAG, tag.len, const_cast<char*>(tag.data));
3411+
return EVP_CIPHER_CTX_ctrl(ctx_.get(),
3412+
EVP_CTRL_AEAD_SET_TAG,
3413+
tag.len,
3414+
const_cast<char*>(tag.data)) > 0;
34133415
}
34143416

34153417
bool CipherCtxPointer::setAeadTagLength(size_t length) {
34163418
if (!ctx_) return false;
34173419
return EVP_CIPHER_CTX_ctrl(
3418-
ctx_.get(), EVP_CTRL_AEAD_SET_TAG, length, nullptr);
3420+
ctx_.get(), EVP_CTRL_AEAD_SET_TAG, length, nullptr) > 0;
34193421
}
34203422

34213423
bool CipherCtxPointer::setPadding(bool padding) {
@@ -3485,7 +3487,7 @@ bool CipherCtxPointer::update(const Buffer<const unsigned char>& in,
34853487

34863488
bool CipherCtxPointer::getAeadTag(size_t len, unsigned char* out) {
34873489
if (!ctx_) return false;
3488-
return EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG, len, out);
3490+
return EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG, len, out) > 0;
34893491
}
34903492

34913493
// ============================================================================

0 commit comments

Comments
 (0)