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);
|
xa_destroy(&conn->sessions);
|
||||||
kvfree(conn->request_buf);
|
kvfree(conn->request_buf);
|
||||||
kfree(conn->preauth_info);
|
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);
|
kfree(conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -93,15 +93,19 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk)
|
||||||
return t;
|
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)
|
static void free_transport(struct tcp_transport *t)
|
||||||
{
|
{
|
||||||
kernel_sock_shutdown(t->sock, SHUT_RDWR);
|
kernel_sock_shutdown(t->sock, SHUT_RDWR);
|
||||||
sock_release(t->sock);
|
|
||||||
t->sock = NULL;
|
|
||||||
|
|
||||||
ksmbd_conn_free(KSMBD_TRANS(t)->conn);
|
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);
|
int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz);
|
||||||
struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name);
|
struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name);
|
||||||
|
void ksmbd_free_transport(struct ksmbd_transport *kt);
|
||||||
int ksmbd_tcp_init(void);
|
int ksmbd_tcp_init(void);
|
||||||
void ksmbd_tcp_destroy(void);
|
void ksmbd_tcp_destroy(void);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue