From 792beee31246fd6dfc7fc8c0629b8769a3fabddf Mon Sep 17 00:00:00 2001 From: Kevin Albertson Date: Sun, 7 May 2023 20:50:21 +0000 Subject: [PATCH] MONGOCRYPT-576 Include the error from `mcr_dll_open` in hard error (#638) * add a failing test * add optional status to _try_load_csfle --- src/mongocrypt.c | 17 +++++++++++------ test/test-mongocrypt-csfle-lib.c | 13 +++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/mongocrypt.c b/src/mongocrypt.c index 6036987c6..9ad6d9c76 100644 --- a/src/mongocrypt.c +++ b/src/mongocrypt.c @@ -362,8 +362,10 @@ typedef struct { /** * @brief Attempt to open the CSFLE dynamic library and initialize a vtable for * it. + * + * @param status is an optional status to set an error message if `mcr_dll_open` fails. */ -static _loaded_csfle _try_load_csfle(const char *filepath, _mongocrypt_log_t *log) { +static _loaded_csfle _try_load_csfle(const char *filepath, _mongocrypt_log_t *log, mongocrypt_status_t *status) { // Try to open the dynamic lib mcr_dll lib = mcr_dll_open(filepath); // Check for errors, which are represented by strings @@ -374,6 +376,7 @@ static _loaded_csfle _try_load_csfle(const char *filepath, _mongocrypt_log_t *lo "Error while opening candidate for CSFLE dynamic library [%s]: %s", filepath, lib.error_string.data); + CLIENT_ERR("Error while opening candidate for CSFLE dynamic library [%s]: %s", filepath, lib.error_string.data); // Free resources, which will include the error string mcr_dll_close(lib); // Bad: @@ -476,7 +479,7 @@ static _loaded_csfle _try_find_csfle(mongocrypt_t *crypt) { // Do not allow a plain filename to go through, as that will cause the // DLL load to search the system. mstr_assign(&csfle_cand_filepath, mpath_absolute(csfle_cand_filepath.view, MPATH_NATIVE)); - candidate_csfle = _try_load_csfle(csfle_cand_filepath.data, &crypt->log); + candidate_csfle = _try_load_csfle(csfle_cand_filepath.data, &crypt->log, crypt->status); } } else { // No override path was specified, so try to find it on the provided @@ -498,7 +501,7 @@ static _loaded_csfle _try_find_csfle(mongocrypt_t *crypt) { } } // Try to load the file: - candidate_csfle = _try_load_csfle(csfle_cand_filepath.data, &crypt->log); + candidate_csfle = _try_load_csfle(csfle_cand_filepath.data, &crypt->log, NULL /* status */); if (candidate_csfle.okay) { // Stop searching: break; @@ -817,9 +820,11 @@ static bool _try_enable_csfle(mongocrypt_t *crypt) { // If a crypt_shared override path was specified, but we did not succeed in // loading crypt_shared, that is a hard-error. if (crypt->opts.crypt_shared_lib_override_path.data && !found.okay) { - CLIENT_ERR("A crypt_shared override path was specified [%s], but we failed to " - "open a dynamic library at that location", - crypt->opts.crypt_shared_lib_override_path.data); + // Wrap error with additional information. + CLIENT_ERR("A crypt_shared override path was specified [%s], but we failed to open a dynamic " + "library at that location. Load error: [%s]", + crypt->opts.crypt_shared_lib_override_path.data, + mongocrypt_status_message(crypt->status, NULL /* len */)); return false; } diff --git a/test/test-mongocrypt-csfle-lib.c b/test/test-mongocrypt-csfle-lib.c index 88d1f69a1..217166b1c 100644 --- a/test/test-mongocrypt-csfle-lib.c +++ b/test/test-mongocrypt-csfle-lib.c @@ -158,6 +158,18 @@ static void _test_csfle_not_loaded_with_bypassqueryanalysis(_mongocrypt_tester_t mongocrypt_destroy(crypt); } +// _test_override_error_includes_reason test changes of MONGOCRYPT-576: the error message from mcr_dll_open is +// propagated. +static void _test_override_error_includes_reason(_mongocrypt_tester_t *tester) { + mongocrypt_t *crypt = get_test_mongocrypt(tester); + // Set an incorrect override path. + mongocrypt_setopt_set_crypt_shared_lib_path_override(crypt, "invalid_path_to_crypt_shared.so"); + ASSERT_FAILS(mongocrypt_init(crypt), crypt, "Error while opening candidate"); + BSON_ASSERT(mongocrypt_crypt_shared_lib_version_string(crypt, NULL) == NULL); + BSON_ASSERT(mongocrypt_crypt_shared_lib_version(crypt) == 0); + mongocrypt_destroy(crypt); +} + void _mongocrypt_tester_install_csfle_lib(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_csfle_no_paths); INSTALL_TEST(_test_csfle_not_found); @@ -168,4 +180,5 @@ void _mongocrypt_tester_install_csfle_lib(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_csfle_path_override_fail); INSTALL_TEST(_test_cur_exe_path); INSTALL_TEST(_test_csfle_not_loaded_with_bypassqueryanalysis); + INSTALL_TEST(_test_override_error_includes_reason); }