Skip to content

Commit ad0057f

Browse files
gregkhsmfrench
authored andcommitted
ksmbd: fix mechToken leak when SPNEGO decode fails after token alloc
The kernel ASN.1 BER decoder calls action callbacks incrementally as it walks the input. When ksmbd_decode_negTokenInit() reaches the mechToken [2] OCTET STRING element, ksmbd_neg_token_alloc() allocates conn->mechToken immediately via kmemdup_nul(). If a later element in the same blob is malformed, then the decoder will return nonzero after the allocation is already live. This could happen if mechListMIC [3] overrunse the enclosing SEQUENCE. decode_negotiation_token() then sets conn->use_spnego = false because both the negTokenInit and negTokenTarg grammars failed. The cleanup at the bottom of smb2_sess_setup() is gated on use_spnego: if (conn->use_spnego && conn->mechToken) { kfree(conn->mechToken); conn->mechToken = NULL; } so the kfree is skipped, causing the mechToken to never be freed. This codepath is reachable pre-authentication, so untrusted clients can cause slow memory leaks on a server without even being properly authenticated. Fix this up by not checking check for use_spnego, as it's not required, so the memory will always be properly freed. At the same time, always free the memory in ksmbd_conn_free() incase some other failure path forgot to free it. Cc: Namjae Jeon <linkinjeon@kernel.org> Cc: Steve French <smfrench@gmail.com> Cc: Sergey Senozhatsky <senozhatsky@chromium.org> Cc: Tom Talpey <tom@talpey.com> Cc: linux-cifs@vger.kernel.org Cc: <stable@kernel.org> Assisted-by: gregkh_clanker_t1000 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 53370cf commit ad0057f

2 files changed

Lines changed: 2 additions & 1 deletion

File tree

fs/smb/server/connection.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ void ksmbd_conn_free(struct ksmbd_conn *conn)
9696
xa_destroy(&conn->sessions);
9797
kvfree(conn->request_buf);
9898
kfree(conn->preauth_info);
99+
kfree(conn->mechToken);
99100
if (atomic_dec_and_test(&conn->refcnt)) {
100101
conn->transport->ops->free_transport(conn->transport);
101102
kfree(conn);

fs/smb/server/smb2pdu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1915,7 +1915,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
19151915
else if (rc)
19161916
rsp->hdr.Status = STATUS_LOGON_FAILURE;
19171917

1918-
if (conn->use_spnego && conn->mechToken) {
1918+
if (conn->mechToken) {
19191919
kfree(conn->mechToken);
19201920
conn->mechToken = NULL;
19211921
}

0 commit comments

Comments
 (0)