[MONGOCRYPT-241] libmongocrypt uses asserts and terminates application processes Created: 31/Jan/20  Updated: 30/Mar/22

Status: Backlog
Project: Libmongocrypt
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Oleg Pudeyev (Inactive) Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to MONGOCRYPT-242 libmongocrypt aborts when mongocrypt_... Backlog
is related to MONGOCRYPT-243 libmongocrypt segfaults if a handle i... Backlog
is related to MONGOCRYPT-208 Gracefully handle OOM Backlog

 Description   

While running FLE tests in the Ruby driver I received this output:

speed% COMPRESSORS=zlib MONGO_RUBY_DRIVER_LINT=1 PATH=/usr/local/m/versions/4.2:$PATH LIBMONGOCRYPT_PATH=~/tmp/libmongocrypt.so aCLIENT_DEBUG=1  MONGODB_URI=mongodb://localhost:14220'/?compressors=zlib' bs spec/integration/auto_encryption_spec.rb:139
Run options: include {:locations=>{"./spec/integration/auto_encryption_spec.rb"=>[139]}}                                
/data/mci/dd0591b7a0680c7f9aceb9cc30394457/libmongocrypt/src/mongocrypt-buffer.c:38 _make_owned(): precondition failed: buf->data
speed% echo $?
134

It appears that libmongocrypt calls BSON_ASSERT which in turn calls abort() when the value evaluates to zero.

In this case my entire Ruby process was destroyed without a stack trace. BSON_ASSERT provided file & line number for the failing assertion but no stack trace leading up to the failing assertion. If the code segfaulted the Ruby runtime would have provided a stack trace including both Ruby and the C functions up to the point of the segfault (see for example https://github.com/p-mongo/tests/blob/master/ruby-ext-stack-trace/output-ffi-2.7.log#L27).

Because the failure did not produce a Ruby stack trace, it is very challenging to determine where one should start debugging this failure, since I would need to identify the Ruby code that is failing (or causing libmongocrypt to fail).

If such a failure occurs in a typical Ruby web application, it would essentially perform a DOS attack on the application as the entire process is terminated.

I think libmongocrypt should:

1. Perform all required checks including internal state assertions in a way that is part of normal method flow, i.e. not conditioned on DEBUG-like preprocessor defines being enabled;

2. Propagate errors detected in all of the above checks to the calling driver/application, with appropriate information to diagnose the source of the error;

3. Not call abort or otherwise terminate the running process, but instead fail the individual operation being performed with an appropriate failure status code and/or diagnostics.


Generated at Thu Feb 08 09:08:17 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.