Fix memory leaks from some ses fields when cifs_negotiate_protocol() or cifs_setup_session() fails in cifs_get_smb_ses(). A leak from ses->domainName has also been identified in setup_ntlmv2_rsp() when session setup fails. These has been reported by kmemleak. Signed-off-by: Enzo Matsumiya <ematsumiya@xxxxxxx> --- v2: replace kfree by kfree_sensitive() for ses->password fs/cifs/cifsencrypt.c | 5 +++++ fs/cifs/connect.c | 22 ++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 8f7835ccbca1..6b681b7084f5 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -680,6 +680,11 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) unlock: cifs_server_unlock(ses->server); setup_ntlmv2_rsp_ret: + if (rc && ses->domainName) { + kfree(ses->domainName); + ses->domainName = NULL; + } + kfree(tiblob); return rc; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 3da5da9f16b0..7d8cd0f85ade 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2215,7 +2215,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) cifs_dbg(FYI, "Existing smb sess not found\n"); ses = sesInfoAlloc(); if (ses == NULL) - goto get_ses_fail; + goto out; /* new SMB session uses our server ref */ ses->server = server; @@ -2227,19 +2227,19 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) if (ctx->username) { ses->user_name = kstrdup(ctx->username, GFP_KERNEL); if (!ses->user_name) - goto get_ses_fail; + goto out_free_ses; } /* ctx->password freed at unmount */ if (ctx->password) { ses->password = kstrdup(ctx->password, GFP_KERNEL); if (!ses->password) - goto get_ses_fail; + goto out_free_username; } if (ctx->domainname) { ses->domainName = kstrdup(ctx->domainname, GFP_KERNEL); if (!ses->domainName) - goto get_ses_fail; + goto out_free_pw; } strscpy(ses->workstation_name, ctx->workstation_name, sizeof(ses->workstation_name)); @@ -2273,7 +2273,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) spin_unlock(&ses->chan_lock); if (rc) - goto get_ses_fail; + goto out_free_domain; /* * success, put it on the list and add it as first channel @@ -2290,8 +2290,18 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) return ses; -get_ses_fail: +out_free_domain: + kfree(ses->domainName); + ses->domainName = NULL; +out_free_pw: + kfree_sensitive(ses->password); + ses->password = NULL; +out_free_username: + kfree(ses->user_name); + ses->user_name = NULL; +out_free_ses: sesInfoFree(ses); +out: free_xid(xid); return ERR_PTR(rc); } -- 2.35.3