From 9918577312bc9c993568e16e732ab8d611fcb656 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 7 Oct 2024 07:23:39 +1000 Subject: [PATCH] libsmb2: fix cb_data leak when session fails during early connect Signed-off-by: Ronnie Sahlberg --- include/libsmb2-private.h | 1 + lib/init.c | 1 + lib/libsmb2.c | 10 ++++++---- lib/sync.c | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/libsmb2-private.h b/include/libsmb2-private.h index 1f00ac99..fb155795 100644 --- a/include/libsmb2-private.h +++ b/include/libsmb2-private.h @@ -152,6 +152,7 @@ struct smb2_context { smb2_error_cb error_cb; smb2_command_cb connect_cb; void *connect_data; + void *connect_cb_data; int credits; diff --git a/lib/init.c b/lib/init.c index 67c358fc..9a55453d 100644 --- a/lib/init.c +++ b/lib/init.c @@ -363,6 +363,7 @@ void smb2_destroy_context(struct smb2_context *smb2) free(smb2->session_key); smb2->session_key = NULL; + free(smb2->connect_cb_data); free(discard_const(smb2->user)); free(discard_const(smb2->server)); free(discard_const(smb2->share)); diff --git a/lib/libsmb2.c b/lib/libsmb2.c index 2f4e1ad8..2cdf8ba6 100644 --- a/lib/libsmb2.c +++ b/lib/libsmb2.c @@ -538,16 +538,18 @@ free_c_data(struct smb2_context *smb2, struct connect_data *c_data) #endif } + if (smb2->connect_data == c_data) { + smb2->connect_data = NULL; /* to prevent double-free in smb2_destroy_context */ + } + if (smb2->connect_cb_data == c_data->cb_data) { + smb2->connect_cb_data = NULL; + } free(c_data->utf8_unc); free(c_data->utf16_unc); free(discard_const(c_data->server)); free(discard_const(c_data->share)); free(discard_const(c_data->user)); free(c_data); - - if (smb2->connect_data == c_data) { - smb2->connect_data = NULL; /* to prevent double-free in smb2_destroy_context */ - } } static void diff --git a/lib/sync.c b/lib/sync.c index 68ba15d9..1a94e805 100644 --- a/lib/sync.c +++ b/lib/sync.c @@ -132,6 +132,8 @@ int smb2_connect_share(struct smb2_context *smb2, smb2_set_error(smb2, "Failed to allocate sync_cb_data"); return -ENOMEM; } + free(smb2->connect_cb_data); + smb2->connect_cb_data = cb_data; rc = smb2_connect_share_async(smb2, server, share, user, connect_cb, cb_data); if (rc < 0) {