From: Arran Cudbard-Bell Date: Mon, 3 Aug 2026 17:47:19 +0000 (-0600) Subject: tls/bio: detach both dbuffs from the shared buffer in one helper X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5774db7d7994da32741cedf4dc337edf921ee28;p=thirdparty%2Ffreeradius-server.git tls/bio: detach both dbuffs from the shared buffer in one helper The in/out dbuffs are bound to the same talloc buffer. finalise, finalise_bstr, and thread_local_clear each hand-rolled clearing the buff pointers; a single helper now enforces the invariant that both dbuffs forget the buffer together. --- diff --git a/src/lib/tls/bio.c b/src/lib/tls/bio.c index 8efa09c127a..af93cb57068 100644 --- a/src/lib/tls/bio.c +++ b/src/lib/tls/bio.c @@ -163,6 +163,19 @@ static int _tls_bio_talloc_gets_cb(BIO *bio, char *buf, int size) return (int)to_copy; } +/** Detach both dbuffs from the shared backing buffer + * + * The in/out dbuffs are bound to the same talloc buffer, so when the buffer + * is freed, or ownership is handed to a caller, both dbuffs must forget the + * buffer together. A stale sibling pointer double-frees in the destructor, + * or trips the "BIO not finalised" assert on reuse. + */ +static inline CC_HINT(always_inline) void tls_bio_dbuff_detach(fr_tls_bio_dbuff_t *bd) +{ + bd->dbuff_in.buff = NULL; + bd->dbuff_out.buff = NULL; +} + /** Finalise a talloc aggregation buffer, returning the underlying talloc array holding the data * * @return @@ -179,8 +192,7 @@ uint8_t *fr_tls_bio_dbuff_finalise(fr_tls_bio_dbuff_t *bd) fr_dbuff_trim_talloc(&bd->dbuff_in, SIZE_MAX); buff = bd->dbuff_in.buff; - bd->dbuff_in.buff = NULL; - bd->dbuff_out.buff = NULL; + tls_bio_dbuff_detach(bd); return buff; } @@ -201,8 +213,7 @@ char *fr_tls_bio_dbuff_finalise_bstr(fr_tls_bio_dbuff_t *bd) fr_dbuff_trim_talloc(&bd->dbuff_in, SIZE_MAX); buff = bd->dbuff_in.buff; - bd->dbuff_in.buff = NULL; - bd->dbuff_out.buff = NULL; + tls_bio_dbuff_detach(bd); talloc_set_type(buff, char); return (char *)buff; @@ -319,7 +330,7 @@ void fr_tls_bio_dbuff_thread_local_clear(void) if (unlikely(!bd->dbuff_in.buff)) return; fr_dbuff_free_talloc(&bd->dbuff_in); - bd->dbuff_out.buff = NULL; + tls_bio_dbuff_detach(bd); } /** Frees the thread local TALLOC bio and its underlying OpenSSL BIO *