From e33a0d65ecc8d7cc2f398dd634f84fbe7fbff546 Mon Sep 17 00:00:00 2001 From: Aleksey Sanin Date: Thu, 1 Oct 2026 18:08:02 -0400 Subject: [PATCH] Enabled std=c23/stc=c99 for all builds; fixed Valgrind suppressions; updated release notes --- configure.ac | 53 +++++++++++---- docs/md/index.md | 27 +++++--- docs/md/news.md | 37 +++++++++- src/buffer.c | 4 +- src/mscng/x509vfy.c | 6 +- src/mscrypto/x509vfy.c | 7 +- tests/testrun.sh | 11 ++- tests/valgrind-gcrypt.supp | 104 +++++++++++++++++----------- tests/valgrind-nss.supp | 73 ++------------------ tests/valgrind-openssl.supp | 132 +++--------------------------------- tests/valgrind.supp | 52 ++++++++++++++ 11 files changed, 233 insertions(+), 273 deletions(-) create mode 100644 tests/valgrind.supp diff --git a/configure.ac b/configure.ac index d9482678a..d1c44b94f 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,10 @@ AC_CONFIG_HEADERS([config.h]) # to make m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +dnl save the user-provided CFLAGS so we can detect an explicit -std= later +dnl and not override it with our own choice of the C standard +XMLSEC_CFLAGS_USER="$CFLAGS" + dnl dnl Check the environment dnl @@ -2711,13 +2715,6 @@ elif test "z$build_with_gcc" = "zyes" ; then CFLAGS="$CFLAGS -Wformat-overflow=2" fi - dnl GCC >= 14: --std=c23 (added in GCC 14) - if test "$gcc_major_ver" -ge 14 ; then - CFLAGS="$CFLAGS -std=c23" - else - CFLAGS="$CFLAGS -std=c99" - fi - AC_MSG_RESULT([yes]) elif test "z$build_with_clang" = "zyes" ; then dnl Flags supported since Clang 3.x (always available in any modern Clang) @@ -2735,18 +2732,44 @@ elif test "z$build_with_clang" = "zyes" ; then CFLAGS="$CFLAGS -Wdouble-promotion -Wnull-dereference" fi - dnl Clang >= 18: --std=c23 (added in Clang 18) - if test "$clang_major_ver" -ge 18 ; then - CFLAGS="$CFLAGS -std=c23" - else - CFLAGS="$CFLAGS -std=c99" - fi - AC_MSG_RESULT([yes]) else AC_MSG_RESULT([disabled (unsupported compiler)]) fi +dnl ========================================================================== +dnl C standard: use C23 if the compiler (recent GCC or Clang) supports it. +dnl C23 provides memset_explicit() which xmlSecMemCleanse() prefers for +dnl secure zeroing of sensitive data. +dnl ========================================================================== +AC_MSG_CHECKING([for C23 support]) +case " $XMLSEC_CFLAGS_USER " in + *" -std="*) + AC_MSG_RESULT([no (custom -std= in CFLAGS)]) + ;; + *) + XMLSEC_CFLAGS_SAVE="$CFLAGS" + CFLAGS="$CFLAGS -std=c23" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 202311L + #error "the compiler does not support C23" + #endif + ]],[[ + /* compiled as C23 */ + ]])], + [XMLSEC_USE_C23="yes"], + [XMLSEC_USE_C23="no"]) + CFLAGS="$XMLSEC_CFLAGS_SAVE" + if test "z$XMLSEC_USE_C23" = "zyes" ; then + CFLAGS="$CFLAGS -std=c23" + AC_MSG_RESULT([yes]) + else + CFLAGS="$CFLAGS -std=c99" + AC_MSG_RESULT([no (use -std=c99)]) + fi + ;; +esac + dnl ========================================================================== dnl Security hardening flags (GCC/Clang only, enabled by default) dnl @@ -2844,7 +2867,7 @@ else fi dnl ========================================================================== -dnl Secure memset (DEPREACTED in favor or true secure wipe -- see xmlSecMemCleanse) +dnl Secure memset (DEPRECATED in favor of true secure wipe -- see xmlSecMemCleanse) dnl ========================================================================== AC_MSG_CHECKING(for secure memset) AC_ARG_ENABLE([secure-memset], [AS_HELP_STRING([--enable-secure-memset],[enable secure memset compilation flags (DEPRECATED, yes)])]) diff --git a/docs/md/index.md b/docs/md/index.md index edcc9ed38..2b5e94586 100644 --- a/docs/md/index.md +++ b/docs/md/index.md @@ -15,28 +15,39 @@ see the Copyright file in the distribution for details. ## News -- **TBD** +- **October 27, 2026** The [XML Security Library 1.3.13](download.md) release includes the following changes: - (xmlsec-core, **not backward compatible**) Fixed several issues with Relationship transform handling. - To restore the old (broken) behaviour, use `--relationship-legacy` flag (or set corresponding flag in - the `xmlSecDSigCtx` structs in your application code). + To restore the old (broken) behaviour, use `--relationship-legacy` flag (or set the + `XMLSEC_DSIG_FLAGS_RELATIONSHIP_LEGACY` flag in the `xmlSecDSigCtx` struct in your application code). - (xmlsec-core, **not backward compatible**) Restricted the default enabled reference and transform URIs to empty and same document URIs only. Use `--enabled-reference-uris`, `--enabled-retrieval-method-uris`, `--enabled-key-info-reference-uris`, etc. parameters for XMLSec command line tool if local or remote URIs usage is required (or set corresponding flag in the `xmlSecDSigCtx` and `xmlSecEncCtx` structs in your - application code). + application code). The `any` value is now accepted by these options to enable all URI types. - (xmlsec-core, **not backward compatible**) Enforced restrictions on max depth when processing encrypted keys, key agreements, etc. Use the new `--max-encrypted-key-level` option to control the maximum depth level for these use cases. (default is 1). - (xmlsec-core, **not backward compatible**) Include files have been cleaned up to remove unnecessary includes, fix circular dependencies, etc. + - (xmlsec-core, **not backward compatible**) Removed support for negative values in BN string conversion/parsing helpers; + values are now treated as unsigned magnitudes. + - (xmlsec-build, **not backward compatible**) Added '-std=c23' compiler flag for building the library + on compilers that support it or '-std=c99' otherwise (this flag was only enabled with --enable-pedantic builds + in the past). + - (xmlsec-openssl, xmlsec-nss, xmlsec-gnutls, xmlsec-mscng, xmlsec-mscrypto, xmlsec-gcrypt, + **not backward compatible**) Reject zero-length CBC padding blocks in all CBC finalization paths. + - (xmlsec-mscng) Added support for using both current user and local machine certificates store for verifying + the certificates (new `xmlSecMSCngAppGetCurrentUserCertStoreName()` / `xmlSecMSCngAppGetLocalMachineCertStoreName()` + APIs; `xmlSecMSCngAppGetCertStoreName` is now a deprecated alias). + - (xmlsec-nss) Hardened CRL verification: CRLs without `thisUpdate` / `nextUpdate` are rejected, and the CRL + issuer certificate is chain-verified with CA usage. - (xmlsec-build, **not backward compatible**) Added `--enable-hardening` option to `configure` script and `hardening` option to `configure.ps1` script to enable security hardening flags on GCC, Clang, and MSVC when the compiler version and the target architecture support it (default: `yes`). - - (xmlsec-openssl) Added checks to enforce full consumption of parsed DER objects. - - (xmlsec-mscng) Added support for using both current user and local machine certificates store for verifying - the certificates. - - (xmlsec-mscng) Enforced HMAC length checks similar to other crypto backends. + - (xmlsec-build) Deprecated the `--enable-secure-memset` option (memory cleansing is now always built in with + the new `xmlSecMemCleanse()` function) and removed the test-only `--enable-skm` option; the fuzz targets in + `apps/oss-fuzz/` are now built and run by `make check` / `nmake check` by default. - (xmlsec-windows) Added `apps` option to `configure.ps1` to control whether the command-line binaries in the `apps/` folder are built (default: `yes`). - Many other small fixes (see [commit log](https://github.com/lsh123/xmlsec/commits/xmlsec_1_3_13) for more details). diff --git a/docs/md/news.md b/docs/md/news.md index 2df2a7c34..b8342fee5 100644 --- a/docs/md/news.md +++ b/docs/md/news.md @@ -1,8 +1,41 @@ # XML Security Library: News -- **TBD** +- **October 27, 2026** The [XML Security Library 1.3.13](download.md) release includes the following changes: - - Several other small fixes (see [more details](https://github.com/lsh123/xmlsec/commits/xmlsec_1_3_13)). + - (xmlsec-core, **not backward compatible**) Fixed several issues with Relationship transform handling. + To restore the old (broken) behaviour, use `--relationship-legacy` flag (or set the + `XMLSEC_DSIG_FLAGS_RELATIONSHIP_LEGACY` flag in the `xmlSecDSigCtx` struct in your application code). + - (xmlsec-core, **not backward compatible**) Restricted the default enabled reference and transform URIs + to empty and same document URIs only. Use `--enabled-reference-uris`, `--enabled-retrieval-method-uris`, + `--enabled-key-info-reference-uris`, etc. parameters for XMLSec command line tool if local or remote URIs + usage is required (or set corresponding flag in the `xmlSecDSigCtx` and `xmlSecEncCtx` structs in your + application code). The `any` value is now accepted by these options to enable all URI types. + - (xmlsec-core, **not backward compatible**) Enforced restrictions on max depth when processing encrypted keys, + key agreements, etc. Use the new `--max-encrypted-key-level` option to control the maximum depth level for + these use cases. (default is 1). + - (xmlsec-core, **not backward compatible**) Include files have been cleaned up to remove unnecessary includes, + fix circular dependencies, etc. + - (xmlsec-core, **not backward compatible**) Removed support for negative values in BN string conversion/parsing helpers; + values are now treated as unsigned magnitudes. + - (xmlsec-build, **not backward compatible**) Added '-std=c23' compiler flag for building the library + on compilers that support it or '-std=c99' otherwise (this flag was only enabled with --enable-pedantic builds + in the past). + - (xmlsec-openssl, xmlsec-nss, xmlsec-gnutls, xmlsec-mscng, xmlsec-mscrypto, xmlsec-gcrypt, + **not backward compatible**) Reject zero-length CBC padding blocks in all CBC finalization paths. + - (xmlsec-mscng) Added support for using both current user and local machine certificates store for verifying + the certificates (new `xmlSecMSCngAppGetCurrentUserCertStoreName()` / `xmlSecMSCngAppGetLocalMachineCertStoreName()` + APIs; `xmlSecMSCngAppGetCertStoreName` is now a deprecated alias). + - (xmlsec-nss) Hardened CRL verification: CRLs without `thisUpdate` / `nextUpdate` are rejected, and the CRL + issuer certificate is chain-verified with CA usage. + - (xmlsec-build, **not backward compatible**) Added `--enable-hardening` option to `configure` script and + `hardening` option to `configure.ps1` script to enable security hardening flags on GCC, Clang, and MSVC + when the compiler version and the target architecture support it (default: `yes`). + - (xmlsec-build) Deprecated the `--enable-secure-memset` option (memory cleansing is now always built in with + the new `xmlSecMemCleanse()` function) and removed the test-only `--enable-skm` option; the fuzz targets in + `apps/oss-fuzz/` are now built and run by `make check` / `nmake check` by default. + - (xmlsec-windows) Added `apps` option to `configure.ps1` to control whether the command-line binaries in + the `apps/` folder are built (default: `yes`). + - Many other small fixes (see [commit log](https://github.com/lsh123/xmlsec/commits/xmlsec_1_3_13) for more details). - **June 23, 2026** The [XML Security Library 1.3.12](download.md) release includes the following changes: diff --git a/src/buffer.c b/src/buffer.c index ad81b95e7..7e2614292 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -10,10 +10,10 @@ * @brief Binary memory buffer functions. */ -/* Required for xmlSecMemCleanse when compiled with --enable-pedantic (i.e. with -std=c99 or -std=c23) (also see configure.ac) */ +/* Required for xmlSecMemCleanse when compiled with -std=c99 or -std=c23 (also see configure.ac) */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) #define _GNU_SOURCE -#endif +#endif /* defined(__GNUC__) && !defined(_GNU_SOURCE) */ #include "globals.h" diff --git a/src/mscng/x509vfy.c b/src/mscng/x509vfy.c index e204214db..e9f07380e 100644 --- a/src/mscng/x509vfy.c +++ b/src/mscng/x509vfy.c @@ -1437,7 +1437,6 @@ xmlSecMSCngX509GetCertName(const xmlChar* name) { static BYTE* xmlSecMSCngCertStrToName(DWORD dwCertEncodingType, LPTSTR pszX500, DWORD dwStrType, DWORD* len) { BYTE* str = NULL; - LPCTSTR ppszError = NULL; xmlSecAssert2(pszX500 != NULL, NULL); xmlSecAssert2(len != NULL, NULL); @@ -1448,7 +1447,7 @@ xmlSecMSCngCertStrToName(DWORD dwCertEncodingType, LPTSTR pszX500, DWORD dwStrTy * (both byte counts), even in a Unicode build where sizeof(TCHAR) == 2; the buffer * below is sized as sizeof(TCHAR) * (*len + 1), which is always >= *len + 1 bytes. * See https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certstrtoname */ - if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType, NULL, NULL, len, &ppszError)) { + if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType, NULL, NULL, len, NULL)) { /* this might not be an error, string might just not exist */ return(NULL); } @@ -1460,8 +1459,7 @@ xmlSecMSCngCertStrToName(DWORD dwCertEncodingType, LPTSTR pszX500, DWORD dwStrTy } memset(str, 0, sizeof(TCHAR) * ((*len) + 1)); - if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType, - NULL, str, len, NULL)) { + if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType, NULL, str, len, NULL)) { xmlSecMSCngLastError("CertStrToName", NULL); xmlFree(str); return(NULL); diff --git a/src/mscrypto/x509vfy.c b/src/mscrypto/x509vfy.c index 08e57b72a..c7a5ee72b 100644 --- a/src/mscrypto/x509vfy.c +++ b/src/mscrypto/x509vfy.c @@ -1041,13 +1041,11 @@ xmlSecMSCryptoX509StoreFinalize(xmlSecKeyDataStorePtr store) { static BYTE* xmlSecMSCryptoCertStrToName(DWORD dwCertEncodingType, LPCTSTR pszX500, DWORD dwStrType, DWORD* len) { BYTE* str = NULL; - LPCTSTR ppszError = NULL; xmlSecAssert2(pszX500 != NULL, NULL); xmlSecAssert2(len != NULL, NULL); - if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType, - NULL, NULL, len, &ppszError)) { + if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType, NULL, NULL, len, NULL)) { /* this might not be an error, string might just not exist */ return(NULL); } @@ -1059,8 +1057,7 @@ xmlSecMSCryptoCertStrToName(DWORD dwCertEncodingType, LPCTSTR pszX500, DWORD dwS } memset(str, 0, sizeof(TCHAR) * ((*len) + 1)); - if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType, - NULL, str, len, NULL)) { + if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType, NULL, str, len, NULL)) { xmlSecMSCryptoError("CertStrToName", NULL); xmlFree(str); return(NULL); diff --git a/tests/testrun.sh b/tests/testrun.sh index 1808ebc92..a84af7c1c 100755 --- a/tests/testrun.sh +++ b/tests/testrun.sh @@ -51,16 +51,15 @@ fi # # Valgrind # +valgrind_suppression="--suppressions=$topfolder/valgrind.supp" if [ "z$crypto" = "zopenssl" ] ; then - valgrind_suppression="--suppressions=$topfolder/valgrind-openssl.supp" + valgrind_suppression="$valgrind_suppression --suppressions=$topfolder/valgrind-openssl.supp" elif [ "z$crypto" = "znss" ] ; then - valgrind_suppression="--suppressions=$topfolder/valgrind-nss.supp" + valgrind_suppression="$valgrind_suppression --suppressions=$topfolder/valgrind-nss.supp" elif [ "z$crypto" = "zgcrypt" ] ; then - valgrind_suppression="--suppressions=$topfolder/valgrind-gcrypt.supp" + valgrind_suppression="$valgrind_suppression --suppressions=$topfolder/valgrind-gcrypt.supp" elif [ "z$crypto" = "zgnutls" ] ; then - valgrind_suppression="--suppressions=$topfolder/valgrind-gnutls.supp" -else - valgrind_suppression="" + valgrind_suppression="$valgrind_suppression --suppressions=$topfolder/valgrind-gnutls.supp" fi valgrind_options="--leak-check=full --show-reachable=yes --num-callers=32 --track-origins=yes -s" diff --git a/tests/valgrind-gcrypt.supp b/tests/valgrind-gcrypt.supp index d4333efa5..99cc841e8 100644 --- a/tests/valgrind-gcrypt.supp +++ b/tests/valgrind-gcrypt.supp @@ -2,12 +2,6 @@ # # Errors to suppress by default with GCrypt # -# Note: several suppressions below reference non-exported libgcrypt symbols -# (global_init, do_randomize, _gcry_rngcsprng_randomize, _gcry_mpi_randomize). -# Valgrind can only resolve those when libgcrypt is built with a symbol table -# or debug info; on a stripped distribution build they silently stop matching, -# so reachable leaks from those paths may surface as unsuppressed reports. -# # Format of this file is: # { # name_of_suppression @@ -22,18 +16,20 @@ # } ##----------------------------------------------------------------------## - -{ - global_init -> malloc - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - ... - fun:global_init - ... - fun:main -} - +# +# libgcrypt keeps per-process working state (random generator pools, +# MPI/PK working buffers) in process-global variables until exit. The +# state is allocated lazily on first use (version check, key +# generation, signing, verification) and is not released by any public +# API, so it shows up as a "still reachable" residual at the end of +# every xmlsec1 invocation that exercises the corresponding path. +# +# Entries match on exported libgcrypt symbols wherever possible, so they +# work on both stripped and unstripped distribution builds. Where the +# allocation stack carries no exported libgcrypt symbol (gcry_randomize() +# transfers control into non-exported code; see below), the entry is +# anchored on the xmlsec1 caller frame instead. +# { gcry_check_version -> malloc Memcheck:Leak @@ -46,75 +42,101 @@ } { - gcry_randomize -> malloc + gcry_pk_genkey -> malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... - fun:gcry_randomize + fun:gcry_pk_genkey ... fun:main } { - gcry_pk_genkey -> malloc + gcry_pk_sign -> malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... - fun:gcry_pk_genkey + fun:gcry_pk_sign ... fun:main } { - xmlSecGCryptGenerateRandom -> malloc + gcry_pk_verify -> malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... - fun:_gcry_rngcsprng_randomize - ... - fun:xmlSecGCryptGenerateRandom + fun:gcry_pk_verify ... fun:main } +# +# The 2 x 664 B RNG working buffers are allocated inside libgcrypt on the +# first strong random request. In libgcrypt >= 1.10 gcry_randomize() +# transfers control directly (without a call) to internal, non-exported +# functions once the RNG state is already initialized, as it is after +# gcry_check_version(), so the allocation stack carries no exported +# libgcrypt symbol and an entry ending in gcry_randomize can never match. +# The allocation is therefore anchored on the xmlsec1 caller instead. +# Without this entry the buffers show up as a "still reachable" residual +# (1,328 bytes in 2 blocks) in every run whose first strong random request +# goes through symmetric key or key data generation. +# { - xmlSecGCryptDsaSign -> do_randomize -> malloc + gcry_randomize -> malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... - fun:do_randomize - ... - fun:xmlSecGCryptDsaSign + fun:xmlSecGCryptGenerateRandom ... fun:main } +# +# The same 2 x 664 B RNG working buffers are allocated when the first +# strong random request in the process goes through RSA key transport +# decryption: gcry_pk_decrypt() generates strong random for RSA blinding. +# Unlike the gcry_randomize() paths above, the gcry_pk_decrypt() frame is +# an exported symbol and appears in the allocation stack, so this entry +# anchors on it directly. +# +# Note: this entry, unlike the entries above, is not terminated by +# fun:main. On deep call chains (e.g. key loading through +# RetrievalMethod) the allocation stack exceeds the --num-callers limit +# of the test harness and is truncated before main, so a fun:main anchor +# would fail to match. The anchor function itself is specific enough: +# the only allocation that stays reachable under it is libgcrypt's own +# per-process working state. +# { - xmlSecGCryptRsaPkcs1Sign -> _gcry_mpi_randomize -> malloc + gcry_pk_decrypt -> malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... - fun:_gcry_mpi_randomize - ... - fun:xmlSecGCryptRsaPkcs1Sign - ... - fun:main + fun:gcry_pk_decrypt } +# +# The same buffers are also allocated when the first strong random request +# in the process is the random IV generated by +# xmlSecGCryptBlockCipherCtxInit() (src/gcrypt/ciphers.c), which calls +# gcry_randomize() directly. The gcry_randomize() frame does not appear in +# the allocation stack for the same reason as in the +# xmlSecGCryptGenerateRandom entry above, so this entry is anchored on the +# xmlsec1 caller frame instead. As with the entry above, it is not +# terminated by fun:main (see the note there). +# { - xmlSecGCryptBlockCipherCtxInit -> _gcry_rngcsprng_randomize -> malloc + xmlSecGCryptBlockCipherCtxInit -> malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... - fun:_gcry_rngcsprng_randomize - ... fun:xmlSecGCryptBlockCipherCtxInit - ... - fun:main } diff --git a/tests/valgrind-nss.supp b/tests/valgrind-nss.supp index d05455d36..810d962ec 100644 --- a/tests/valgrind-nss.supp +++ b/tests/valgrind-nss.supp @@ -16,72 +16,13 @@ # } ##----------------------------------------------------------------------## -{ - NSS memcmp/prng_RandomUpdate(Cond) - Memcheck:Cond - fun:memcmp - fun:prng_RandomUpdate -} - -{ - NSS alg_fips*/prng_RandomUpdate(Cond) - Memcheck:Cond - fun:alg_fips* - fun:prng_RandomUpdate -} - -{ - NSS sec_asn1d_parse_leaf/SEC_ASN1*(Cond) - Memcheck:Cond - fun:sec_asn1d* - fun:SEC_ASN1* -} - -{ - NSS DES_Do1Block(Value4) - Memcheck:Value4 - fun:DES_Do1Block - fun:DES_EDE* -} - -{ - NSS memcmp/prng(Value4) - Memcheck:Value4 - fun:memcmp - fun:*prng* -} - -{ - NSS *memset/SECITEM*(Value4) - Memcheck:Value4 - fun:*mem* - fun:*SECITEM* -} - -{ - NSS *FreeArena*(Cond) - Memcheck:Cond - fun:*Arena* - fun:*Arena* -} - -{ - NSS rijndael*(Value4) - Memcheck:Value4 - fun:rijndael* -} - -{ - NSS_InitReadWrite -> malloc (definite) - Memcheck:Leak - match-leak-kinds: definite - fun:malloc - ... - fun:NSS_InitReadWrite - ... - fun:main -} - +# +# NSS keeps one-time initialisation state (crypto module setup, +# PKCS#11 token configuration) in process-global variables until exit. +# The allocations are made during NSS_InitReadWrite / +# PK11_ConfigurePKCS11 and are not released by any public API, so they +# show up as a "still reachable" residual in every xmlsec1 invocation. +# { NSS_InitReadWrite -> malloc (reachable) Memcheck:Leak diff --git a/tests/valgrind-openssl.supp b/tests/valgrind-openssl.supp index 1c2eafbfe..45a711744 100644 --- a/tests/valgrind-openssl.supp +++ b/tests/valgrind-openssl.supp @@ -16,119 +16,13 @@ # } ##----------------------------------------------------------------------## -# The BN_*/bn_* suppressions below mirror the bignum entries from -# upstream OpenSSL's own test/valgrind.supp and are kept broad on purpose. - -{ - OpenSSL BN_*(Cond) - Memcheck:Cond - fun:BN_* -} - -{ - OpenSSL BN_*(Value4) - Memcheck:Value4 - fun:BN_* -} - -{ - OpenSSL bn_*(Cond) - Memcheck:Cond - fun:bn_* -} - -{ - OpenSSL bn_*(Value4) - Memcheck:Value4 - fun:bn_* -} - -{ - OpenSSL AES_encrypt*/(Value4) - Memcheck:Value4 - fun:AES_encrypt - fun:AES_cbc_encrypt -} - -{ - OpenSSL DES_encrypt*(Value4) - Memcheck:Value4 - fun:DES_encrypt2 - fun:DES_encrypt3 -} - -{ - OpenSSL RSA_padding_add_PKCS1_type_2(Cond) - Memcheck:Cond - fun:RSA_padding_add_PKCS1_type_2 - fun:RSA_eay_public_encrypt - ... -} - -{ - OpenSSL EVP_DecryptFinal_ex(Cond) - Memcheck:Cond - ... - fun:EVP_DecryptFinal_ex - fun:EVP_CipherFinal_ex - fun:xmlSecOpenSSLEvpBlockCipherCtxUpdateBlock - ... -} - -{ - ossl_provider_set_operation_bit -> malloc - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - fun:ossl_provider_set_operation_bit - ... -} -{ - ossl_provider_set_operation_bit -> calloc - Memcheck:Leak - match-leak-kinds: reachable - fun:calloc - fun:ossl_provider_set_operation_bit - ... -} -{ - ossl_provider_set_operation_bit -> realloc - Memcheck:Leak - match-leak-kinds: reachable - fun:realloc - fun:ossl_provider_set_operation_bit - ... -} -{ - OSSL_PROVIDER_try_load -> malloc - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - ... - fun:OSSL_PROVIDER_try_load - ... - fun:main -} -{ - OSSL_PROVIDER_try_load -> realloc - Memcheck:Leak - match-leak-kinds: reachable - fun:realloc - ... - fun:OSSL_PROVIDER_try_load - ... - fun:main -} -{ - OSSL_PROVIDER_try_load -> calloc - Memcheck:Leak - match-leak-kinds: reachable - fun:calloc - ... - fun:OSSL_PROVIDER_try_load - ... - fun:main -} +# +# OpenSSL keeps one-time initialisation state (provider loading, +# algorithm dispatch) in process-global variables until exit. The +# allocations are made during OPENSSL_init_crypto on the first use of +# the library and are not released by any public API, so they show up +# as a small "still reachable" residual in every xmlsec1 invocation. +# { OPENSSL_init_crypto -> malloc Memcheck:Leak @@ -139,16 +33,7 @@ ... fun:main } -{ - OPENSSL_init_crypto -> realloc - Memcheck:Leak - match-leak-kinds: reachable - fun:realloc - ... - fun:OPENSSL_init_crypto - ... - fun:main -} + { OPENSSL_init_crypto -> calloc Memcheck:Leak @@ -159,4 +44,3 @@ ... fun:main } - diff --git a/tests/valgrind.supp b/tests/valgrind.supp new file mode 100644 index 000000000..c7f1408a9 --- /dev/null +++ b/tests/valgrind.supp @@ -0,0 +1,52 @@ +##----------------------------------------------------------------------## +# +# Errors and leaks to suppress by default, common to all crypto backends +# +# The entries in this file target defects in third-party libraries +# that trigger independently of the crypto backend in use. They are +# loaded in addition to the per-backend suppression files +# (valgrind-openssl.supp, valgrind-nss.supp, valgrind-gcrypt.supp, +# valgrind-gnutls.supp). +# +# Format of this file is: +# { +# name_of_suppression +# kind: one of Param Value1 Value2 Value4 Value8 +# Free Addr1 Addr2 Addr4 Addr8 +# Cond (previously known as Value0) +# (if Param: name of system call param, if Free: name of free-ing fn) +# caller0 name, or /name/of/so/file.so +# caller1 name, or ditto +# (optionally: caller2 name) +# (optionally: caller3 name) +# } + +##----------------------------------------------------------------------## + +## +## libxml2: the catalog resolve cache is never released +## +## When a non-local (e.g. http://) URI is resolved through the default +## entity loader, libxml2 lazily creates a global URI-to-location +## resolve cache (the static variable xmlCatalogResolveCache in +## catalog.c). The hash table and the cached key strings are kept +## allocated until process exit: neither xmlCatalogCleanup() nor +## xmlCleanupParser() releases the cache (verified with libxml2 2.15.2), +## and no public API is provided to do so. +## +## As a result, every xmlsec1 invocation that resolves a non-local URI +## reports a small "still reachable" residual at exit (732-737 bytes in +## 4 blocks: the hash structure, the hash table and the cached key +## strings). The cache is intentionally retained by libxml2 to speed up +## repeated URI resolutions, so this is not an xmlsec1 leak; the +## residual is suppressed here. +{ + xmlCreateURLParserCtxt -> xmlACatalogResolveURI -> malloc + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:xmlACatalogResolveURI + ... + fun:xmlCreateURLParserCtxt +}