From: Bob Beck Date: Wed, 7 Jan 2026 23:21:10 +0000 (-0700) Subject: Allow testing the valgrind suppression file in CI X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf39120c27047683c90f675ab1f1fbfa286cc026;p=thirdparty%2Fopenssl.git Allow testing the valgrind suppression file in CI Skip the OPENSSL_cleanup() call from the openssl app and in tests when OSSL_USE_VALGRIND environment variable is set. This can be used in the CI to test the valgrind suppressions. Builds upon https://github.com/openssl/openssl/pull/29573 Reviewed-by: Neil Horman Reviewed-by: Saša Nedvědický Reviewed-by: Tomas Mraz MergeDate: Tue Feb 10 14:00:54 2026 (Merged from https://github.com/openssl/openssl/pull/29575) --- diff --git a/apps/openssl.c b/apps/openssl.c index 2d587e22498..e869910e829 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -21,6 +21,15 @@ #include #include #include + +#if defined __has_include +/* Any compiler you're going to run valgrind on has this */ +#if __has_include() +#include +#define OPENSSL_VALGRIND_H_INCLUDED +#endif +#endif /* defined(__has_include) */ + /* Needed to get the other O_xxx flags. */ #ifdef OPENSSL_SYS_VMS #include @@ -372,6 +381,31 @@ end: #ifndef OPENSSL_NO_SECURE_MEMORY CRYPTO_secure_malloc_done(); #endif + +#if defined(OPENSSL_VALGRIND_TEST) +#if defined(OPENSSL_VALGRIND_H_INCLUDED) +#if defined(RUNNING_ON_VALGRIND) + /* + * Enable special behaviour if we are compiled with + * OPENSSL_VALGRIND_TEST defined. + * + * Somewhat paradoxically, we do *NOT* want to clean up normally + * when running our tests using valgrind in order to test the + * suppression file which we will ship with the distribution. We + * set the OSSL_USE_VALGRIND environment variable for this + * purpose, but we only want to dodge cleanup when running under + * valgrind, *and* that environment variable is set. If you run + * this under valgrind without that environment variable set, it + * will still call OPENSSL_cleanup normally. + * + */ + if (RUNNING_ON_VALGRIND && getenv("OSSL_USE_VALGRIND") != NULL) + EXIT(ret); +#endif /* defined(RUNNING_ON_VALGRIND) */ +#else +#error "OPENSSL_VALGRIND_TEST is defined, but could not be included!" +#endif /* defined(OPENSSL_VALGRIND_H_INCLUDED) */ +#endif /* defined(OPENSSL_VALGRIND_TEST) */ OPENSSL_cleanup(); EXIT(ret); } diff --git a/doc/internal/man7/valgrind-tests.pod b/doc/internal/man7/valgrind-tests.pod new file mode 100644 index 00000000000..e5b31b868d5 --- /dev/null +++ b/doc/internal/man7/valgrind-tests.pod @@ -0,0 +1,49 @@ +=pod + +=head1 NAME + +valgrind-tests - How we test for valgrind + +=head1 DESCRIPTION + +We have CI jobs that run to verify that the suppression file we +ship with valgrind functions correctly when users use valgrind +with full leak checking. + +While doing full leak checking shows the global objects the library +frees on exit as leaks, which really are not leaks, it is a chore +to continuously tell people to ignore the results from the library. + +==head1 ENVIRONMENT + +Normally the openssl application main program and the test main program +always call OPENSSL_cleanup(). This means that running these applications +under valgrind will not show anything. Therefore we selectively disable +the call to OPENSSL_cleanup() when running these applications for +testing. + +the test environment sets the environment variable + +I when using valgrind to run our tests. + +As such the main programs above are instrumented so that when they +are built and the header can be seen in the +include path, the macro RUNNING_ON_VALGRIND is used at exit time +to test to see if the program is actually running under valgrind. + +If the program is running under valgrind, the program checks to +see if I is set in the environment. If so, +the call to OPENSSL_cleanup() is skipped on exit. This will ensure +the library globals are noticed by valgrind with full leak checking +ensuring our suppression file is working in CI. + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/test/testutil/main.c b/test/testutil/main.c index 2d7c88c3831..c0d3ffe7fd3 100644 --- a/test/testutil/main.c +++ b/test/testutil/main.c @@ -12,6 +12,19 @@ #include "output.h" #include "tu_local.h" +#if defined __has_include +/* Any compiler you're going to run valgrind on has this */ +#if __has_include() +#include +#define OPENSSL_VALGRIND_H_INCLUDED +#endif +#endif /* defined(__has_include) */ + +/* + * At some point we should consider looking at this function with a view to + * moving most/all of this into onfree handlers in OSSL_LIB_CTX. + */ + int main(int argc, char *argv[]) { int ret = EXIT_FAILURE; @@ -40,6 +53,20 @@ int main(int argc, char *argv[]) end: ret = pulldown_test_framework(ret); test_close_streams(); +#if defined(OPENSSL_VALGRIND_H_INCLUDED) && defined(RUNNING_ON_VALGRIND) + /* + * Somewhat paradoxically, we do *NOT* want to clean up normally + * when running our tests using valgrind in order to test the + * suppression file which we will ship with the distribution. We + * set the OSSL_USE_VALGRIND environment variable for this + * purpose, but we only want to dodge cleanup when running under + * valgrind, *and* that environment variable is set. If you run + * this under valgrind without that environment variable set, it + * will still call OPENSSL_cleanup normally. + */ + if (RUNNING_ON_VALGRIND && getenv("OSSL_USE_VALGRIND") != NULL) + return ret; +#endif /* defined(OPENSSL_VALGRIND_H_INCLUDED) && defined(RUNNING_ON_VALGRIND) */ OPENSSL_cleanup(); return ret; }