From 1d758b2cd2f13af02319274c4e48cd7a2dc62e42 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 8 Jun 2026 09:19:42 +0200 Subject: [PATCH] message: Avoid memory leak if string buffer for message is too small This leaked 40 or 80 bytes per parsed message for the enumerators that were not destroyed. While triggering an OOM condition will require quite a lot of messages and the DoS protection also helps avoiding that this is triggered quickly, it all depends on the memory constraints of the system and the time available to the attacker. Also, if IKEv1 is allowed, it could get quicker as the lack of message IDs doesn't allow dismissing unexpected messages before parsing them. Fixes: 092958c89d52 ("fixed payload debug message") Fixes: 6a4a47511f75 ("Show contents of the CP payload in message_t stringification") Fixes: CVE-2026-78127 --- src/libcharon/encoding/message.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 8da9a1d71e47..a4bf9cb26b73 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -1398,7 +1398,7 @@ static char* get_string(private_message_t *this, char *buf, int len) payload->get_type(payload)); if (written >= len || written < 0) { - return buf; + goto err; } pos += written; len -= written; @@ -1424,7 +1424,7 @@ static char* get_string(private_message_t *this, char *buf, int len) } if (written >= len || written < 0) { - return buf; + goto err; } pos += written; len -= written; @@ -1454,7 +1454,7 @@ static char* get_string(private_message_t *this, char *buf, int len) eap->get_code(eap), method); if (written >= len || written < 0) { - return buf; + goto err; } pos += written; len -= written; @@ -1495,7 +1495,8 @@ static char* get_string(private_message_t *this, char *buf, int len) attribute->get_type(attribute)); if (written >= len || written < 0) { - return buf; + attributes->destroy(attributes); + goto err; } pos += written; len -= written; @@ -1507,7 +1508,7 @@ static char* get_string(private_message_t *this, char *buf, int len) written = snprintf(pos, len, ")"); if (written >= len || written < 0) { - return buf; + goto err; } pos += written; len -= written; @@ -1529,7 +1530,7 @@ static char* get_string(private_message_t *this, char *buf, int len) } if (written >= len || written < 0) { - return buf; + goto err; } pos += written; len -= written; @@ -1544,7 +1545,7 @@ static char* get_string(private_message_t *this, char *buf, int len) frag->get_total_fragments(frag)); if (written >= len || written < 0) { - return buf; + goto err; } pos += written; len -= written; @@ -1557,16 +1558,16 @@ static char* get_string(private_message_t *this, char *buf, int len) written = snprintf(pos, len, "(%d)", unknown->get_type(unknown)); if (written >= len || written < 0) { - return buf; + goto err; } pos += written; len -= written; } } - enumerator->destroy(enumerator); - - /* remove last space */ snprintf(pos, len, " ]"); + +err: + enumerator->destroy(enumerator); return buf; } #endif -- 2.43.0