mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
ksmbd: fix use-after-free in __smb2_lease_break_noti()
Move tcp_transport free to ksmbd_conn_free. If ksmbd connection is referenced when ksmbd server thread terminates, It will not be freed, but conn->tcp_transport is freed. __smb2_lease_break_noti can be performed asynchronously when the connection is disconnected. __smb2_lease_break_noti calls ksmbd_conn_write, which can cause use-after-free when conn->ksmbd_transport is already freed. Cc: stable@vger.kernel.org Reported-by: Norbert Szetei <norbert@doyensec.com> Tested-by: Norbert Szetei <norbert@doyensec.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
1df0d4c616
commit
21a4e47578
3 changed files with 13 additions and 6 deletions
|
@ -39,8 +39,10 @@ void ksmbd_conn_free(struct ksmbd_conn *conn)
|
|||
xa_destroy(&conn->sessions);
|
||||
kvfree(conn->request_buf);
|
||||
kfree(conn->preauth_info);
|
||||
if (atomic_dec_and_test(&conn->refcnt))
|
||||
if (atomic_dec_and_test(&conn->refcnt)) {
|
||||
ksmbd_free_transport(conn->transport);
|
||||
kfree(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,15 +93,19 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk)
|
|||
return t;
|
||||
}
|
||||
|
||||
void ksmbd_free_transport(struct ksmbd_transport *kt)
|
||||
{
|
||||
struct tcp_transport *t = TCP_TRANS(kt);
|
||||
|
||||
sock_release(t->sock);
|
||||
kfree(t->iov);
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
static void free_transport(struct tcp_transport *t)
|
||||
{
|
||||
kernel_sock_shutdown(t->sock, SHUT_RDWR);
|
||||
sock_release(t->sock);
|
||||
t->sock = NULL;
|
||||
|
||||
ksmbd_conn_free(KSMBD_TRANS(t)->conn);
|
||||
kfree(t->iov);
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz);
|
||||
struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name);
|
||||
void ksmbd_free_transport(struct ksmbd_transport *kt);
|
||||
int ksmbd_tcp_init(void);
|
||||
void ksmbd_tcp_destroy(void);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue