nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
105.13k stars 28.48k forks source link

"crypto.createDecipher().end" results in an abort #38015

Open zyscoder opened 3 years ago

zyscoder commented 3 years ago

What steps will reproduce the bug?

Setup a node instance,

» node

and run the following javascript code.

crypto.createDecipher('aes-128-gcm','').end('str','hex',()=>{})

Then the node instance occurs an abort.

How often does it reproduce? Is there a required condition?

This abort can always be triggered following the steps above.

What is the expected behavior?

If any error occurs, an exception or other similar error-reporting stuff should be thrown. There is no reason to abort the whole node process.

What do you see instead?

» node
Welcome to Node.js v14.15.1.
Type ".help" for more information.
> crypto.createDecipher('aes-128-gcm','').end('str','hex',()=>{})
node[37939]: ../src/string_bytes.cc:433:static v8::Maybe<long unsigned int> node::StringBytes::StorageSize(v8::Isolate*, v8::Local<v8::Value>, node::encoding): Assertion `str->Length() % 2 == 0 && "invalid hex string length"' failed.
 1: 0xa03530 node::Abort() [node]
 2: 0xa035ae  [node]
 3: 0xadb6ba node::StringBytes::StorageSize(v8::Isolate*, v8::Local<v8::Value>, node::encoding) [node]
 4: 0xb389ce node::StringBytes::InlineDecoder::Decode(node::Environment*, v8::Local<v8::String>, node::encoding) [node]
 5: 0xb3982e void node::crypto::Decode<node::crypto::CipherBase>(v8::FunctionCallbackInfo<v8::Value> const&, void (*)(node::crypto::CipherBase*, v8::FunctionCallbackInfo<v8::Value> const&, char const*, unsigned long)) [node]
 6: 0xbe369b  [node]
 7: 0xbe4c46  [node]
 8: 0xbe52c6 v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
 9: 0x13ff259  [node]
[1]    37939 abort (core dumped)  node                                                                                                                                                                                                                   

Additional information

aduh95 commented 3 years ago

@EladKeyshawn First of all I'm not the one reporting the issue. Secondly, that's not how Node.js handles exceptions, as you said we usually try to throw an error that can be caught by the user in JavaScript. Here the program simply crashes (core dumped), which is why I labeled it as valid bug report.

EladKeyshawn commented 3 years ago

@aduh95 what about the fact its deprecated ?

aduh95 commented 3 years ago

I agree users should not be using it, however it's still a bug in the codebase. Maybe a solution would be to remove that deprecated API (it's deprecated since v10.0.0), but I suspect it outlines a bug in the stream implementation which is worth fixing IMHO.

EladKeyshawn commented 3 years ago

@aduh95 I'm not sure it's in the stream implementation, since the error and consequently the abort is caused by the ASSERT used in string_bytes.cc, and the correct stacktrace is printed alright so it seems like the problem comes from the abort() implementation itself. More to note that this problem does not occur in OSX where I tested it.

aduh95 commented 3 years ago

I'm able to reproduce on master (macOS x86_64), with both the createDecipher and createDecipheriv:

> node -e 'crypto.createDecipheriv("aes-128-ccm", Buffer.from("1ed2233fa2223ef5d7df08546049406c", "hex"), Buffer.from("7305220bca40d4c90e1791e9", "hex"), {authTagLength:10}).end("str","hex",()=>{})'
out/Release/node[57020]: ../src/string_bytes.cc:437:static Maybe<size_t> node::StringBytes::StorageSize(v8::Isolate *, Local<v8::Value>, enum encoding): Assertion `str->Length() % 2 == 0 && "invalid hex string length"' failed.
 1: 0x10d6ae895 node::Abort() […/node/out/Release/node]
 2: 0x10d6ae701 node::Assert(node::AssertionInfo const&) […/node/out/Release/node]
 3: 0x10d76c94c node::StringBytes::StorageSize(v8::Isolate*, v8::Local<v8::Value>, node::encoding) […/node/out/Release/node]
 4: 0x10d7b26ae node::StringBytes::InlineDecoder::Decode(node::Environment*, v8::Local<v8::String>, node::encoding) […/node/out/Release/node]
 5: 0x10d7b41bd node::crypto::CipherBase::Update(v8::FunctionCallbackInfo<v8::Value> const&) […/node/out/Release/node]
 6: 0x10d893e5a v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) […/node/out/Release/node]
 7: 0x10d893438 v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) […/node/out/Release/node]
 8: 0x10d8929ff v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) […/node/out/Release/node]
 9: 0x10e10b9b9 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit […/node/out/Release/node]
[2]    57020 abort      out/Release/node -e
> node -e "crypto.createDecipher('aes-128-gcm','').end('str','hex',()=>{})"
out/Release/node[57042]: ../src/string_bytes.cc:437:static Maybe<size_t> node::StringBytes::StorageSize(v8::Isolate *, Local<v8::Value>, enum encoding): Assertion `str->Length() % 2 == 0 && "invalid hex string length"' failed.
 1: 0x105773895 node::Abort() […/node/out/Release/node]
 2: 0x105773701 node::Assert(node::AssertionInfo const&) […/node/out/Release/node]
 3: 0x10583194c node::StringBytes::StorageSize(v8::Isolate*, v8::Local<v8::Value>, node::encoding) […/node/out/Release/node]
 4: 0x1058776ae node::StringBytes::InlineDecoder::Decode(node::Environment*, v8::Local<v8::String>, node::encoding) […/node/out/Release/node]
 5: 0x1058791bd node::crypto::CipherBase::Update(v8::FunctionCallbackInfo<v8::Value> const&) […/node/out/Release/node]
 6: 0x105958e5a v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) […/node/out/Release/node]
 7: 0x105958438 v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) […/node/out/Release/node]
 8: 0x1059579ff v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) […/node/out/Release/node]
 9: 0x1061d09b9 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit […/node/out/Release/node]
[2]    57042 abort      out/Release/node -e
EladKeyshawn commented 3 years ago

it does not reproduce on 14.x

aduh95 commented 3 years ago

@EladKeyshawn what do you see when you run the above commands? FWIW I am able to reproduce on v14.16.0 and v15.13.0.

EladKeyshawn commented 3 years ago
> crypto.createDecipher('aes-128-gcm','').end('str', 'hex')
out/Release/node[88993]: ../src/string_bytes.cc:433:static Maybe<size_t> node::StringBytes::StorageSize(v8::Isolate *, Local<v8::Value>, enum encoding): Assertion `str->Length() % 2 == 0 && "invalid hex string length"' failed.
 1: 0x1000a5dd5 node::Abort() [/Users/eladkeyshawn/OSS/node/out/Release/node]
 2: 0x1000a5c41 node::Assert(node::AssertionInfo const&) [/Users/eladkeyshawn/OSS/node/out/Release/node]
 3: 0x10015d22f node::StringBytes::StorageSize(v8::Isolate*, v8::Local<v8::Value>, node::encoding) [/Users/eladkeyshawn/OSS/node/out/Release/node]
 4: 0x1001b0b4e node::StringBytes::InlineDecoder::Decode(node::Environment*, v8::Local<v8::String>, node::encoding) [/Users/eladkeyshawn/OSS/node/out/Release/node]
 5: 0x1001988bd node::crypto::CipherBase::Update(v8::FunctionCallbackInfo<v8::Value> const&) [/Users/eladkeyshawn/OSS/node/out/Release/node]
 6: 0x100251c6d v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) [/Users/eladkeyshawn/OSS/node/out/Release/node]
 7: 0x1002511fc v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) [/Users/eladkeyshawn/OSS/node/out/Release/node]
 8: 0x100250932 v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) [/Users/eladkeyshawn/OSS/node/out/Release/node]
 9: 0x100a55899 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit [/Users/eladkeyshawn/OSS/node/out/Release/node]
10: 0x1009eeb62 Builtins_InterpreterEntryTrampoline [/Users/eladkeyshawn/OSS/node/out/Release/node]
Abort trap: 6