From c2f1a3a21b4c922cbcf50bf7c009b740141a1e7a Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Tue, 21 Jul 2026 17:51:42 +0200 Subject: [PATCH] publickey: fix `attr` memleak on error in `libssh2_publickey_list_fetch()` In case of error, the last touched list entry could have the `attr` field assigned to an allocated buffer, while still having NULL `packet`. This made the destructore skip this entry and leak `attr`. Fix by initializing all new list entries to zero and freeing entries with either `attr` or `packet` set, up to entry where both are NULL. Reported-by: hyunjiHong on github Fixes #2368 Closes #2380 --- src/publickey.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/publickey.c b/src/publickey.c index 43b8123e62..7db71a4249 100644 --- a/src/publickey.c +++ b/src/publickey.c @@ -941,7 +941,7 @@ int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, goto err_exit; } list = newlist; - memset(&list[keys], 0, sizeof(list[keys])); + memset(&list[keys], 0, (max_keys - keys) * sizeof(list[keys])); } if(pkey->version == 1) { unsigned long comment_len; @@ -1180,10 +1180,9 @@ int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, } /* To be FREEd in libssh2_publickey_list_free() */ list[keys].packet = pkey->listFetch_data; - keys++; - - list[keys].packet = NULL; /* Terminate the list */ pkey->listFetch_data = NULL; + + keys++; break; default: /* Unknown/Unexpected */ @@ -1217,10 +1216,11 @@ void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, session = pkey->channel->session; - while(p->packet) { + while(p->attrs || p->packet) { if(p->attrs) SSH2_FREE(session, p->attrs); - SSH2_FREE(session, p->packet); + if(p->packet) + SSH2_FREE(session, p->packet); p++; }