Commit 790601e03c for strongswan.org

commit 790601e03c45c8d223ecbab5f7627f899245f53d
Author: Armaan Sandhu <armaan.sandhu0504@gmail.com>
Date:   Sat Oct 17 20:57:57 2026 -0400

    encrypted-payload: Avoid cloning freed plaintext on decryption failure

    frag_decrypt() frees this->plain.ptr before decrypting, but leaves the
    chunk pointing to the freed memory.  If decrypt_content() fails before
    it sets the plaintext, which it does for invalid lengths and failed
    integrity checks, the chunk_clone() afterwards copies from the freed
    buffer.  Use chunk_free() so the chunk is cleared and an empty chunk
    is cloned on failure.

    This is not reachable on the normal receive path, where each fragment
    is decrypted once and the plaintext is still empty.

    For consistency, (frag_)encrypt() now uses chunk_free() as a failed
    second call could theoretically cause a double-free.

    Closes strongswan/strongswan#3180

    Fixes: 4c345b15c762 ("ikev2: Add encrypted fragment payload")

diff --git a/src/libcharon/encoding/payloads/encrypted_payload.c b/src/libcharon/encoding/payloads/encrypted_payload.c
index 1e22d0831e..8da06ec27b 100644
--- a/src/libcharon/encoding/payloads/encrypted_payload.c
+++ b/src/libcharon/encoding/payloads/encrypted_payload.c
@@ -513,7 +513,7 @@ METHOD(encrypted_payload_t, encrypt, status_t,
 		return INVALID_STATE;
 	}

-	free(this->encrypted.ptr);
+	chunk_free(&this->encrypted);
 	generator = generator_create();
 	plain = generate(this, generator);
 	assoc = append_header(this, assoc);
@@ -961,7 +961,7 @@ METHOD(encrypted_payload_t, frag_encrypt, status_t,
 			 "transform missing");
 		return INVALID_STATE;
 	}
-	free(this->encrypted.ptr);
+	chunk_free(&this->encrypted);
 	assoc = append_header_frag(this, assoc);
 	/* IKEv2 message IDs are not unique if fragmentation is used, hence include
 	 * the fragment number to make it unique */
@@ -983,7 +983,7 @@ METHOD(encrypted_payload_t, frag_decrypt, status_t,
 			 "transform missing");
 		return INVALID_STATE;
 	}
-	free(this->plain.ptr);
+	chunk_free(&this->plain);
 	assoc = append_header_frag(this, assoc);
 	status = decrypt_content("encrypted fragment payload", this->aead,
 							 this->encrypted, assoc, &this->plain);