Commit 770bc1b024 for openssl.org

commit 770bc1b024664ac1c32c36896f70933be8120764
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date:   Mon Jun 8 16:45:57 2026 +0200

    mfail: add hard failure return code for failing even for NO_CHECK

    The hard failure return code is meant for NO_CHECK variants to fail if
    there is some failure that should never happen and likely signal a bug.

    Reviewed-by: Norbert Pocs <norbertp@openssl.org>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    MergeDate: Thu Jun 11 16:00:15 2026
    (Merged from https://github.com/openssl/openssl/pull/31356)

diff --git a/test/README.md b/test/README.md
index 2a423d3511..4bc558817f 100644
--- a/test/README.md
+++ b/test/README.md
@@ -194,8 +194,14 @@ run repeatedly, failing one allocation later each iteration. The
 `ADD_MFAIL_NO_CHECK_TEST` variant relaxes the requirement that the test
 return 0 when a failure was triggered. The `ADD_MFAIL_ALL_TESTS` and
 `ADD_MFAIL_ALL_NO_CHECK_TESTS` variants apply the same cycle to each index
-of a parameterised test, the same way `ADD_ALL_TESTS` does. Behavior is
-controlled with the following environment variables:
+of a parameterised test, the same way `ADD_ALL_TESTS` does.
+
+An mfail test returns 1 on success or 0 on failure; under `NO_CHECK` a 0 is
+tolerated since a function may legitimately fail when an allocation fails.
+Returning -1 forces a failure that is reported even under `NO_CHECK`, for
+assertions that must hold regardless of which allocation was made to fail.
+
+Behavior is controlled with the following environment variables:

     OPENSSL_TEST_MFAIL_DISABLE=1    Disable mfail custom allocator installation.

diff --git a/test/testutil/driver.c b/test/testutil/driver.c
index 86eacd4008..54aa2a061a 100644
--- a/test/testutil/driver.c
+++ b/test/testutil/driver.c
@@ -352,7 +352,12 @@ static int mfail_run_test(const TEST_INFO *t, int idx)
                 break;
         } else {
             injections++;
-            if (mfail_was_triggered()) {
+            if (rv == -1) {
+                TEST_error("mfail test '%s': unconditional failure at "
+                           "point %d",
+                    t->test_case_name, mfail_get_point());
+                injection_ok = 0;
+            } else if (mfail_was_triggered()) {
                 if (!no_check && !TEST_int_eq(rv, 0)) {
                     TEST_error("mfail test '%s': allocation failure at "
                                "point %d not handled",