Commit 4b7108ac0f for strongswan.org
commit 4b7108ac0f84fbf40da2b510eb6333afa2a54240
Author: Tobias Brunner <tobias@strongswan.org>
Date: Mon Jun 8 09:19:42 2026 +0200
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
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c
index 8da9a1d71e..a4bf9cb26b 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