From 75347db1e7f8500758ce47ae0644ccad0bc0ccfc Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 09:49:30 -0600 Subject: [PATCH 01/14] Add cxsecShred(). Add cxsecShred() to cxsec.c and cxsec.h. Clean up newline spacing in cxsec.c. --- centrallix-lib/include/cxsec.h | 2 ++ centrallix-lib/src/cxsec.c | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/centrallix-lib/include/cxsec.h b/centrallix-lib/include/cxsec.h index fb82d7e98..31596a044 100644 --- a/centrallix-lib/include/cxsec.h +++ b/centrallix-lib/include/cxsec.h @@ -31,6 +31,8 @@ void cxsecInitialize(); int cxsecVerifySymbol(const char* sym); int cxsecVerifySymbol_n(const char* sym, size_t n); +void cxsecShred(void* data, size_t n_bytes); + #ifndef __GNUC__ #define __attribute__(a) /* hide function attributes from non-GCC compilers */ #endif diff --git a/centrallix-lib/src/cxsec.c b/centrallix-lib/src/cxsec.c index e07980d6d..1494dd733 100644 --- a/centrallix-lib/src/cxsec.c +++ b/centrallix-lib/src/cxsec.c @@ -4,6 +4,9 @@ #include "cxsec.h" #include #include +#include +#include +#include #include /************************************************************************/ @@ -68,6 +71,7 @@ cxsecInitDS(unsigned long* start, unsigned long* end) return; } + void cxsecVerifyDS(unsigned long* start, unsigned long* end, char* file, int line) { @@ -87,6 +91,7 @@ cxsecVerifyDS(unsigned long* start, unsigned long* end, char* file, int line) return; } + void cxsecUpdateDS(unsigned long* start, unsigned long* end, char* file, int line) { @@ -137,6 +142,7 @@ cxsecVerifySymbol(const char* sym) return 0; } + int cxsecVerifySymbol_n(const char* sym, size_t n) { @@ -163,3 +169,24 @@ cxsecVerifySymbol_n(const char* sym, size_t n) return 0; } + +/*** cxssShred() - Erase the given data so that it is no longer readable + *** even in raw memory. This is the same as calling memset_explicit(), + *** except that this function works before C23, when memset_explicit() + *** was added. + *** + *** Also, using this function signifies the intent to scrub possibly + *** sensitive data, which makes code more readable. + *** + *** @param data A pointer to the data buffer to be erased. + *** @param n_bytes The number of bytes allocated to the data buffer. + *** Causes undefined behavior if incorrect. + ***/ +void +cxsecShred(void* data, size_t n_bytes) + { + memset(data, 0, n_bytes); + *(volatile uint8_t*)data = *(volatile uint8_t*)data; + + return; + } From d45db2e0e57fa084c26c7d9af42fa4f5a1f5d9df Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 09:52:33 -0600 Subject: [PATCH 02/14] Replace memset() in centrallix-lib with cxsecShred() when the data looks sensitive. --- centrallix-lib/src/mtsession.c | 18 +++++++++--------- centrallix-lib/src/xringqueue.c | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/centrallix-lib/src/mtsession.c b/centrallix-lib/src/mtsession.c index 015a00193..f3b378811 100644 --- a/centrallix-lib/src/mtsession.c +++ b/centrallix-lib/src/mtsession.c @@ -23,6 +23,7 @@ #include "xstring.h" #include "xhash.h" #include "strtcpy.h" +#include "cxsec.h" /************************************************************************/ /* Centrallix Application Server System */ @@ -272,7 +273,7 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) if (strchr(username,':')) { mssError(1, "MSS", "Attempt to use invalid username '%s'", username); - memset(s, 0, sizeof(MtSession)); + cxsecShred(s, sizeof(MtSession)); nmFree(s,sizeof(MtSession)); return -1; } @@ -284,7 +285,7 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) pw = getpwnam(s->UserName); if (!pw) { - memset(s, 0, sizeof(MtSession)); + cxsecShred(s, sizeof(MtSession)); nmFree(s,sizeof(MtSession)); return -1; } @@ -309,7 +310,7 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) encrypted_pwd = (char*)crypt(s->Password,pwd); if (!encrypted_pwd || strcmp(encrypted_pwd,pwd)) { - memset(s, 0, sizeof(MtSession)); + cxsecShred(s, sizeof(MtSession)); nmFree(s,sizeof(MtSession)); return -1; } @@ -322,7 +323,7 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) if (!altpass_fd) { mssErrorErrno(1, "MSS", "Could not open auth file '%s'", MSS.AuthFile); - memset(s, 0, sizeof(MtSession)); + cxsecShred(s, sizeof(MtSession)); nmFree(s,sizeof(MtSession)); return -1; } @@ -335,7 +336,7 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) if (t == MLX_TOK_ERROR) { mssError(0, "MSS", "Could not read auth file '%s'", MSS.AuthFile); - memset(s, 0, sizeof(MtSession)); + cxsecShred(s, sizeof(MtSession)); nmFree(s,sizeof(MtSession)); mlxCloseSession(altpass_lxs); fdClose(altpass_fd, 0); @@ -365,7 +366,7 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) encrypted_pwd = (char*)crypt(s->Password,pwd); if (strcmp(encrypted_pwd,pwd)) { - memset(s, 0, sizeof(MtSession)); + cxsecShred(s, sizeof(MtSession)); nmFree(s,sizeof(MtSession)); return -1; } @@ -373,7 +374,7 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) } else { - memset(s, 0, sizeof(MtSession)); + cxsecShred(s, sizeof(MtSession)); nmFree(s,sizeof(MtSession)); return -1; } @@ -445,7 +446,7 @@ mssEndSession(pMtSession s) xhDeInit(&s->Params); xaDeInit(&(s->ErrList)); xaRemoveItem(&(MSS.Sessions),xaFindItem(&(MSS.Sessions),(void*)s)); - memset(s, 0, sizeof(MtSession)); + cxsecShred(s, sizeof(MtSession)); nmFree(s,sizeof(MtSession)); return 0; @@ -836,4 +837,3 @@ mssGetParam(char* paramname) return p->Value; } - diff --git a/centrallix-lib/src/xringqueue.c b/centrallix-lib/src/xringqueue.c index 944366cf9..f940de40c 100644 --- a/centrallix-lib/src/xringqueue.c +++ b/centrallix-lib/src/xringqueue.c @@ -5,6 +5,7 @@ #include #include #include +#include "cxsec.h" #include "xringqueue.h" #include "newmalloc.h" @@ -53,7 +54,7 @@ xrqDeInit(pXRingQueue this) /** Free the items **/ nmSysFree(this->Items); - memset(this,0,sizeof(XRingQueue)); + cxsecShred(this,sizeof(XRingQueue)); return 0; } @@ -81,7 +82,7 @@ xrqEnqueue(pXRingQueue this, void* item) memcpy(ptr+this->nAlloc,ptr,(this->nextIn)*sizeof(void*)); /** zero out it's old location to be safe **/ - memset(ptr,0,sizeof(void*)*this->nextIn); + cxsecShred(ptr,sizeof(void*)*this->nextIn); /** update the location of nextIn **/ this->nextIn+=this->nAlloc; @@ -138,4 +139,3 @@ xrqCount(pXRingQueue this) { return ((this->nextIn-this->nextOut)+this->nAlloc)%this->nAlloc; } - From 93b9338e6603d6685bb68c518fb794c62ffa7b64 Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 09:54:31 -0600 Subject: [PATCH 03/14] Update cxssShred() in Centrallix. Update cxssShred() to use cxsecShred() instead of memset(). Improve the signature of cxssShred(). Improve the doc comment on cxssShred(). Clean up. --- centrallix/cxss/cxss_utility.c | 27 ++++++++++++++++++--------- centrallix/include/cxss/cxss.h | 3 +-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/centrallix/cxss/cxss_utility.c b/centrallix/cxss/cxss_utility.c index 16367d2ca..c081bd813 100644 --- a/centrallix/cxss/cxss_utility.c +++ b/centrallix/cxss/cxss_utility.c @@ -8,6 +8,7 @@ #include "cxlib/xarray.h" #include "cxlib/xhash.h" #include "cxlib/mtlexer.h" +#include "cxlib/cxsec.h" #include "cxss/cxss.h" /************************************************************************/ @@ -128,16 +129,25 @@ cxssGenerateHexKey(char* hexkey, size_t len) } -/*** cxssShred - erase the given data so that it is no longer readable - *** even in raw memory. At this point, basically the same as memset(). - *** But using this function signifies the intent and makes the code - *** more readable. + +/*** cxssShred() - Erase the given data so that it is no longer readable + *** even in raw memory. This is the same as calling memset_explicit(), + *** except that this function works before C23, when memset_explicit() + *** was added. + *** + *** Also, using this function signifies the intent to scrub possibly + *** sensitive data, which makes code more readable. + *** + *** @param data A pointer to the data buffer to be erased. + *** @param n_bytes The number of bytes allocated to the data buffer. + *** Causes undefined behavior if incorrect. ***/ -int -cxssShred(unsigned char* data, size_t n_bytes) +void +cxssShred(void* data, size_t n_bytes) { - memset(data, '\0', n_bytes); - return 0; + cxsecShred(data, n_bytes); + + return; } @@ -155,4 +165,3 @@ cxssAddEntropy(unsigned char* data, size_t n_bytes, int entropy_bits_estimate) return rval; } - diff --git a/centrallix/include/cxss/cxss.h b/centrallix/include/cxss/cxss.h index 98fa11af1..94d2dbec0 100644 --- a/centrallix/include/cxss/cxss.h +++ b/centrallix/include/cxss/cxss.h @@ -129,7 +129,7 @@ int cxssHexify(unsigned char* bindata, size_t bindatalen, char* hexdata, size_t int cxss_i_Hexify(unsigned char* bindata, size_t bindatalen, char* hexdata, size_t hexdatalen); int cxssGenerateKey(unsigned char* key, size_t n_bytes); int cxssGenerateHexKey(char* hexkey, size_t len); -int cxssShred(unsigned char* data, size_t n_bytes); +void cxssShred(void* data, size_t n_bytes); int cxssAddEntropy(unsigned char* data, size_t n_bytes, int entropy_bits_estimate); /*** Context/Authentication/Endorsement stack functions ***/ @@ -170,4 +170,3 @@ int cxssAuthorizeSpec(char* objectspec, int access_type, int log_mode); int cxssAuthorize(char* domain, char* type, char* path, char* attr, int access_type, int log_mode); #endif /* not defined _CXSS_H */ - From be8af3870833f6d79f3cbb35faf667d6bf75b53e Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 09:55:42 -0600 Subject: [PATCH 04/14] Fix circular dependency in policy.h. Remove #include "cxss/cxss.h". Add #include directives to include only the things that policy.h actually needs. Clean up. --- centrallix/include/cxss/policy.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/centrallix/include/cxss/policy.h b/centrallix/include/cxss/policy.h index aeee11ce8..1daf610f4 100644 --- a/centrallix/include/cxss/policy.h +++ b/centrallix/include/cxss/policy.h @@ -1,7 +1,9 @@ #ifndef _CXSS_POLICY_H #define _CXSS_POLICY_H -#include "cxss/cxss.h" +#include "cxlib/datatypes.h" +#include "cxlib/xarray.h" +#include "obj.h" /************************************************************************/ /* Centrallix Application Server System */ @@ -89,4 +91,3 @@ typedef struct _CXSSPOL CxssPolicy, *pCxssPolicy; #endif /* defined _CXSS_POLICY_H */ - From bf26035c58dc6be3025a6024ab0fa78857c5beef Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 09:57:09 -0600 Subject: [PATCH 05/14] Replace memset() in centrallix with cxss() when the data looks sensitive. --- centrallix/cxss/cxss_credentials_mgr.c | 4 ++-- centrallix/cxss/cxss_crypto.c | 4 ++-- centrallix/cxss/cxss_keystream.c | 3 +-- centrallix/netdrivers/net_http_sess.c | 3 +-- centrallix/osdrivers/objdrv_mysql.c | 5 +++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/centrallix/cxss/cxss_credentials_mgr.c b/centrallix/cxss/cxss_credentials_mgr.c index 806069d63..1817e38d9 100644 --- a/centrallix/cxss/cxss_credentials_mgr.c +++ b/centrallix/cxss/cxss_credentials_mgr.c @@ -11,6 +11,7 @@ #include "cxss/credentials_mgr.h" #include "cxss/credentials_db.h" #include "cxss/crypto.h" +#include "cxss/cxss.h" #include /* Database context */ @@ -285,7 +286,7 @@ cxssAddResource(const char *cxss_userid, const char *resource_id, const char *au } /* Erase plaintext random key from memory */ - memset(rand_key, 0, sizeof(rand_key)); + cxssShred(rand_key, sizeof(rand_key)); /* Build struct */ UserResc.CXSS_UserID = cxss_userid; @@ -442,4 +443,3 @@ cxssDeleteResource(const char *cxss_userid, const char *resource_id) } return CXSS_MGR_SUCCESS; } - diff --git a/centrallix/cxss/cxss_crypto.c b/centrallix/cxss/cxss_crypto.c index 2c6373766..dcb5f2375 100644 --- a/centrallix/cxss/cxss_crypto.c +++ b/centrallix/cxss/cxss_crypto.c @@ -8,6 +8,7 @@ #include #include #include +#include "cxss/cxss.h" #include "cxss/crypto.h" #include "cxss/credentials_db.h" @@ -498,8 +499,7 @@ void cxssDestroyKey(char *key, size_t keylength) { if (key && keylength >= 0) { - memset(key, 0, keylength); + cxssShred(key, keylength); free(key); } } - diff --git a/centrallix/cxss/cxss_keystream.c b/centrallix/cxss/cxss_keystream.c index 6e94cc29d..97a5dc3f7 100644 --- a/centrallix/cxss/cxss_keystream.c +++ b/centrallix/cxss/cxss_keystream.c @@ -201,9 +201,8 @@ cxssKeystreamFree(pCxssKeystreamState kstate) if (kstate->Context) EVP_CIPHER_CTX_free(kstate->Context); - memset(kstate, 0, sizeof(CxssKeystreamState)); + cxssShred(kstate, sizeof(CxssKeystreamState)); nmFree(kstate, sizeof(CxssKeystreamState)); return 0; } - diff --git a/centrallix/netdrivers/net_http_sess.c b/centrallix/netdrivers/net_http_sess.c index ccc6106e7..f96ae61ed 100644 --- a/centrallix/netdrivers/net_http_sess.c +++ b/centrallix/netdrivers/net_http_sess.c @@ -265,7 +265,7 @@ nht_i_UnlinkSess(pNhtSessionData sess) xhDeInit(sess->CachedApps); nmFree(sess->CachedApps, sizeof(XHashTable)); xhnDeInitContext(&(sess->Hctx)); - memset(sess, 0, sizeof(NhtSessionData)); + cxssShred(sess, sizeof(NhtSessionData)); nmFree(sess, sizeof(NhtSessionData)); } @@ -906,4 +906,3 @@ nht_i_LookupApp(char* akey, pNhtSessionData *sess, pNhtAppGroup *group, pNhtApp return -1; } - diff --git a/centrallix/osdrivers/objdrv_mysql.c b/centrallix/osdrivers/objdrv_mysql.c index 807cbeb74..e259e14cb 100644 --- a/centrallix/osdrivers/objdrv_mysql.c +++ b/centrallix/osdrivers/objdrv_mysql.c @@ -15,6 +15,7 @@ #include "cxlib/strtcpy.h" #include "cxlib/qprintf.h" #include "cxlib/util.h" +#include "cxss/cxss.h" #include #include @@ -248,7 +249,7 @@ mysd_internal_GetConn(pMysdNode node) { /** Got disconnected. Discard the connection. **/ mysql_close(&conn->Handle); - memset(conn->Password, 0, sizeof(conn->Password)); + cxssShred(conn->Password, sizeof(conn->Password)); xaRemoveItem(&node->Conns, i); nmFree(conn, sizeof(MysdConn)); i--; @@ -297,7 +298,7 @@ mysd_internal_GetConn(pMysdNode node) } conn = (pMysdConn)xaGetItem(&node->Conns, found); mysql_close(&conn->Handle); - memset(conn->Password, 0, sizeof(conn->Password)); + cxssShred(conn->Password, sizeof(conn->Password)); xaRemoveItem(&node->Conns, found); nmFree(conn, sizeof(MysdConn)); } From 8b66a92f700d9d69102714ba7d6ae7a3f6531b4c Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 11:21:15 -0600 Subject: [PATCH 06/14] Fix obscure shredding issues that I barely understand. --- centrallix-lib/src/cxsec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/centrallix-lib/src/cxsec.c b/centrallix-lib/src/cxsec.c index 1494dd733..ee2655c9a 100644 --- a/centrallix-lib/src/cxsec.c +++ b/centrallix-lib/src/cxsec.c @@ -186,7 +186,8 @@ void cxsecShred(void* data, size_t n_bytes) { memset(data, 0, n_bytes); - *(volatile uint8_t*)data = *(volatile uint8_t*)data; - + if (n_bytes > 0) + ((volatile uint8_t*)data)[n_bytes - 1]; + return; } From 79ada3be07ef29367c4dc1f052e76723473994d1 Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 12:12:25 -0600 Subject: [PATCH 07/14] Add m4 macro code to check for memset_explicit(), memset_s(), and explicit_bzero(). --- centrallix-lib/aclocal.m4 | 56 +++++++++++++++++++ centrallix-lib/configure.ac | 3 + .../include/cxlibconfig-internal.h.in | 8 +++ 3 files changed, 67 insertions(+) diff --git a/centrallix-lib/aclocal.m4 b/centrallix-lib/aclocal.m4 index cd74b27b2..3b273514a 100644 --- a/centrallix-lib/aclocal.m4 +++ b/centrallix-lib/aclocal.m4 @@ -52,6 +52,62 @@ AC_DEFUN(CHECK_BUILTIN_EXPECT, ] ) +dnl check if memset_explicit(), memset_s(), explicit_bzero() are available. +AC_DEFUN(CHECK_MEMSET, + [ + AC_MSG_CHECKING(if memset_explicit is available) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include ], + [ + char buf[16]; + memset_explicit(buf, 0, sizeof(buf)); + ] + )], + [ + AC_DEFINE([HAVE_MEMSET_EXPLICIT], [1], [Define if memset_explicit is available]) + AC_MSG_RESULT([yes]) + ], + [AC_MSG_RESULT([no])] + ) + + AC_MSG_CHECKING(if memset_s is available) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #define __STDC_WANT_LIB_EXT1__ 1 + #include + ], + [ + char buf[16]; + memset_s(buf, sizeof(buf), 0, sizeof(buf)); + ] + )], + [ + AC_DEFINE([HAVE_MEMSET_S], [1], [Define if memset_s is available]) + AC_MSG_RESULT([yes]) + ], + [AC_MSG_RESULT([no])] + ) + + AC_MSG_CHECKING(if explicit_bzero is available) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include ], + [ + char buf[16]; + explicit_bzero(buf, sizeof(buf)); + ] + )], + [ + AC_DEFINE([HAVE_EXPLICIT_BZERO], [1], [Define if explicit_bzero is available]) + AC_MSG_RESULT([yes]) + ], + [AC_MSG_RESULT([no])] + ) + ] +) + dnl check if gcc allows -fPIC and -pg at the same time AC_DEFUN(CHECK_PROFILE, [ diff --git a/centrallix-lib/configure.ac b/centrallix-lib/configure.ac index 189ff466f..7ca1446a9 100644 --- a/centrallix-lib/configure.ac +++ b/centrallix-lib/configure.ac @@ -43,6 +43,9 @@ CHECK_MAKEDEPEND dnl Check for __builtin_expect() CHECK_BUILTIN_EXPECT +dnl Check for memset_explicit(), memset_s(), and explicit_bzero(). +CHECK_MEMSET + dnl Check if -pg is allowed with -fPIC AH_TEMPLATE([USE_PROFILE], [Define for profiling]) CHECK_PROFILE diff --git a/centrallix-lib/include/cxlibconfig-internal.h.in b/centrallix-lib/include/cxlibconfig-internal.h.in index 6649e4478..eafb5e23f 100644 --- a/centrallix-lib/include/cxlibconfig-internal.h.in +++ b/centrallix-lib/include/cxlibconfig-internal.h.in @@ -35,3 +35,11 @@ /* defined to 1 if SIOCOUTQ is available */ #undef HAVE_SIOCOUTQ +/* defined to 1 if memset_explict() is available */ +#undef HAVE_MEMSET_EXPLICIT + +/* defined to 1 if memset_s() is available */ +#undef HAVE_MEMSET_S + +/* defined to 1 if explicit_bzero() is available */ +#undef HAVE_EXPLICIT_BZERO From 14b8fd6a862d90a51ca0c29ad6fab6b6c25b8d43 Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 12:12:42 -0600 Subject: [PATCH 08/14] Update generated files. --- centrallix-lib/configure | 102 ++++++++++++++++++++ centrallix-lib/include/cxlibconfig-all.h.in | 9 ++ 2 files changed, 111 insertions(+) diff --git a/centrallix-lib/configure b/centrallix-lib/configure index 4995f514f..809b4897f 100755 --- a/centrallix-lib/configure +++ b/centrallix-lib/configure @@ -4110,6 +4110,108 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if memset_explicit is available" >&5 +$as_echo_n "checking if memset_explicit is available... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + char buf16; + memset_explicit(buf, 0, sizeof(buf)); + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + +$as_echo "#define HAVE_MEMSET_EXPLICIT 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if memset_s is available" >&5 +$as_echo_n "checking if memset_s is available... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define __STDC_WANT_LIB_EXT1__ 1 + #include + +int +main () +{ + + char buf16; + memset_s(buf, sizeof(buf), 0, sizeof(buf)); + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + +$as_echo "#define HAVE_MEMSET_S 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if explicit_bzero is available" >&5 +$as_echo_n "checking if explicit_bzero is available... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + char buf16; + explicit_bzero(buf, sizeof(buf)); + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + +$as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -fPIC and -pg can be used at the same time" >&5 $as_echo_n "checking if -fPIC and -pg can be used at the same time... " >&6; } diff --git a/centrallix-lib/include/cxlibconfig-all.h.in b/centrallix-lib/include/cxlibconfig-all.h.in index 50ff22993..834c73f67 100644 --- a/centrallix-lib/include/cxlibconfig-all.h.in +++ b/centrallix-lib/include/cxlibconfig-all.h.in @@ -9,6 +9,9 @@ /* Define to 1 if you have the `endservent' function. */ #undef HAVE_ENDSERVENT +/* Define if explicit_bzero is available */ +#undef HAVE_EXPLICIT_BZERO + /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H @@ -24,6 +27,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define if memset_explicit is available */ +#undef HAVE_MEMSET_EXPLICIT + +/* Define if memset_s is available */ +#undef HAVE_MEMSET_S + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT From 2848a95ec58e7452dd01e79170cdbd6a933b9063 Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 12:13:58 -0600 Subject: [PATCH 09/14] Update cxsecShred() to use better implementations, if available. Add code to use memset_explicit(), if available. Add code to use memset_s(), if available. Add code to use explicit_bzero(), if available. Add code to fall back to the original volatile memset if no other options are available. --- centrallix-lib/src/cxsec.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/centrallix-lib/src/cxsec.c b/centrallix-lib/src/cxsec.c index 1494dd733..e6745b7b0 100644 --- a/centrallix-lib/src/cxsec.c +++ b/centrallix-lib/src/cxsec.c @@ -185,8 +185,29 @@ cxsecVerifySymbol_n(const char* sym, size_t n) void cxsecShred(void* data, size_t n_bytes) { +#ifdef MEMSET_EXPLICIT +#define CXSEC_FOUND + memset_explicit(data, 0, n_bytes); + return; +#endif + +#ifdef MEMSET_S +#define CXSEC_FOUND + memset_s(data, n_bytes, 0, n_bytes); + return; +#endif + +#ifdef HAVE_EXPLICIT_BZERO +#define CXSEC_FOUND + explicit_bzero(data, n_bytes); + return; +#endif + +#ifndef CXSEC_FOUND +#undef CXSEC_FOUND memset(data, 0, n_bytes); *(volatile uint8_t*)data = *(volatile uint8_t*)data; - +#endif + return; } From f097b4e86c5033f319d00ede2b6d3546e2e6e54e Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 13:57:06 -0600 Subject: [PATCH 10/14] Replace shredding method that AI thought was secure with shredding method that is ACTUALLY secure (I think). --- centrallix-lib/src/cxsec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/centrallix-lib/src/cxsec.c b/centrallix-lib/src/cxsec.c index ee2655c9a..4d3d19af7 100644 --- a/centrallix-lib/src/cxsec.c +++ b/centrallix-lib/src/cxsec.c @@ -185,9 +185,9 @@ cxsecVerifySymbol_n(const char* sym, size_t n) void cxsecShred(void* data, size_t n_bytes) { - memset(data, 0, n_bytes); - if (n_bytes > 0) - ((volatile uint8_t*)data)[n_bytes - 1]; + volatile uint8_t* ptr = (volatile uint8_t*)data; + for (size_t i = 0; i < n_bytes; i++) + ptr[i] = 0; return; } From 51a348e1ed98c977a29f27fe23c99d3f586baca3 Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 17:21:11 -0600 Subject: [PATCH 11/14] Fix m4 macros generating bad code that gave incorrect test results. --- centrallix-lib/aclocal.m4 | 49 +++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/centrallix-lib/aclocal.m4 b/centrallix-lib/aclocal.m4 index 3b273514a..18640db96 100644 --- a/centrallix-lib/aclocal.m4 +++ b/centrallix-lib/aclocal.m4 @@ -56,12 +56,17 @@ dnl check if memset_explicit(), memset_s(), explicit_bzero() are available. AC_DEFUN(CHECK_MEMSET, [ AC_MSG_CHECKING(if memset_explicit is available) - AC_COMPILE_IFELSE( + AC_RUN_IFELSE( [AC_LANG_PROGRAM( [#include ], [ - char buf[16]; + char buf[[16]]; + for (size_t i = 0; i < sizeof(buf); i++) + buf[[i]] = i; memset_explicit(buf, 0, sizeof(buf)); + for (size_t i = 0; i < sizeof(buf); i++) + if (buf[[i]] != 0) + return -1; ] )], [ @@ -72,15 +77,20 @@ AC_DEFUN(CHECK_MEMSET, ) AC_MSG_CHECKING(if memset_s is available) - AC_COMPILE_IFELSE( + AC_RUN_IFELSE( [AC_LANG_PROGRAM( [ #define __STDC_WANT_LIB_EXT1__ 1 #include ], [ - char buf[16]; + char buf[[16]]; + for (size_t i = 0; i < sizeof(buf); i++) + buf[[i]] = i; memset_s(buf, sizeof(buf), 0, sizeof(buf)); + for (size_t i = 0; i < sizeof(buf); i++) + if (buf[[i]] != 0) + return -1; ] )], [ @@ -91,20 +101,25 @@ AC_DEFUN(CHECK_MEMSET, ) AC_MSG_CHECKING(if explicit_bzero is available) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [#include ], - [ - char buf[16]; - explicit_bzero(buf, sizeof(buf)); - ] - )], + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [#include ], [ - AC_DEFINE([HAVE_EXPLICIT_BZERO], [1], [Define if explicit_bzero is available]) - AC_MSG_RESULT([yes]) - ], - [AC_MSG_RESULT([no])] - ) + char buf[[16]]; + for (size_t i = 0; i < sizeof(buf); i++) + buf[[i]] = i; + explicit_bzero(buf, sizeof(buf)); + for (size_t i = 0; i < sizeof(buf); i++) + if (buf[[i]] != 0) + return -1; + ] + )], + [ + AC_DEFINE([HAVE_EXPLICIT_BZERO], [1], [Define if explicit_bzero is available]) + AC_MSG_RESULT([yes]) + ], + [AC_MSG_RESULT([no])] + ) ] ) From 5a8614dd77ef382932fe27be357ae80adb7e3826 Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 17:21:21 -0600 Subject: [PATCH 12/14] Update generated files. --- centrallix-lib/configure | 70 ++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/centrallix-lib/configure b/centrallix-lib/configure index 809b4897f..8f3ab7468 100755 --- a/centrallix-lib/configure +++ b/centrallix-lib/configure @@ -4112,22 +4112,33 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking if memset_explicit is available" >&5 $as_echo_n "checking if memset_explicit is available... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { - char buf16; + char buf[16]; + for (size_t i = 0; i < sizeof(buf); i++) + buf[i] = i; memset_explicit(buf, 0, sizeof(buf)); + for (size_t i = 0; i < sizeof(buf); i++) + if (buf[i] != 0) + return -1; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_run "$LINENO"; then : $as_echo "#define HAVE_MEMSET_EXPLICIT 1" >>confdefs.h @@ -4140,11 +4151,20 @@ else $as_echo "no" >&6; } fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if memset_s is available" >&5 $as_echo_n "checking if memset_s is available... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define __STDC_WANT_LIB_EXT1__ 1 @@ -4154,15 +4174,20 @@ int main () { - char buf16; + char buf[16]; + for (size_t i = 0; i < sizeof(buf); i++) + buf[i] = i; memset_s(buf, sizeof(buf), 0, sizeof(buf)); + for (size_t i = 0; i < sizeof(buf); i++) + if (buf[i] != 0) + return -1; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_run "$LINENO"; then : $as_echo "#define HAVE_MEMSET_S 1" >>confdefs.h @@ -4175,31 +4200,45 @@ else $as_echo "no" >&6; } fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if explicit_bzero is available" >&5 $as_echo_n "checking if explicit_bzero is available... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { - char buf16; - explicit_bzero(buf, sizeof(buf)); + char buf[16]; + for (size_t i = 0; i < sizeof(buf); i++) + buf[i] = i; + explicit_bzero(buf, sizeof(buf)); + for (size_t i = 0; i < sizeof(buf); i++) + if (buf[i] != 0) + return -1; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_run "$LINENO"; then : $as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else @@ -4207,7 +4246,10 @@ else $as_echo "no" >&6; } fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + From 8117c75ad41dfd4f9b18a6ec34e7d0022f66e513 Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 17:21:37 -0600 Subject: [PATCH 13/14] Fix typos in cxsec.c implementation. --- centrallix-lib/src/cxsec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/centrallix-lib/src/cxsec.c b/centrallix-lib/src/cxsec.c index 31ba281d6..c0a5af8a3 100644 --- a/centrallix-lib/src/cxsec.c +++ b/centrallix-lib/src/cxsec.c @@ -1,3 +1,4 @@ +#define __STDC_WANT_LIB_EXT1__ 1 #ifdef HAVE_CONFIG_H #include "cxlibconfig-internal.h" #endif @@ -185,13 +186,13 @@ cxsecVerifySymbol_n(const char* sym, size_t n) void cxsecShred(void* data, size_t n_bytes) { -#ifdef MEMSET_EXPLICIT +#ifdef HAVE_MEMSET_EXPLICIT #define CXSEC_FOUND memset_explicit(data, 0, n_bytes); return; #endif -#ifdef MEMSET_S +#ifdef HAVE_MEMSET_S #define CXSEC_FOUND memset_s(data, n_bytes, 0, n_bytes); return; From 8e33dd7e3d2226a5305b1fb37b401df302973686 Mon Sep 17 00:00:00 2001 From: Lightning11wins Date: Fri, 15 May 2026 17:23:52 -0600 Subject: [PATCH 14/14] Clean up code that defined things we didn't need. --- centrallix-lib/src/cxsec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/centrallix-lib/src/cxsec.c b/centrallix-lib/src/cxsec.c index c0a5af8a3..c5d27c541 100644 --- a/centrallix-lib/src/cxsec.c +++ b/centrallix-lib/src/cxsec.c @@ -1,4 +1,6 @@ +#ifdef HAVE_MEMSET_S #define __STDC_WANT_LIB_EXT1__ 1 +#endif #ifdef HAVE_CONFIG_H #include "cxlibconfig-internal.h" #endif