mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 02:36:02 +00:00
4 ksmbd server fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmWobwQACgkQiiy9cAdy T1GTXgv/amjpAd1kEVwgfyUGvM9rsN+DtojoXt1z5xDkzJrnszI0s/WARz7o2gc/ 6nIOxKWfpxb0QHRcLebZHbN7mrZeelHLyMqbx0Wphy5Y0cUQlq1C50l6xAkua1dd /uPklGZVW9LDRvZYzdwa4Spi0tVwDgsnmK2UiWckCfc1yu9BVz3mg1gtaeg0Z/Z4 caojvSTXdJ/35xKV4udE4lo0PpbCC2h990c5iR8iOXgMuBlgIv3JQYC+3avuXXdS Erneof5Vx9sUV7p7SWCR71VFaWnMsF1/DtXMKTxAJKjYGZPckQGQjxOJeonaRltg 0YjzeMT5/d5Fv3w0L1Mtn9pxyXTQ4ywKJ3Vpm21geuw7pl/70sqdQtg+ujljfN6j uzb6mzwFezp3LGK8RI6h//JKUrnurIM/dc9FuRCoU2N91rfhGuiAvTwzrjh67WW8 HTmsnhNWnWuhH7OQJrOPQVEEs6DSUgA6MvHjslXoj7V+ksoKMe57JyZIr6Hx0CX9 W4Q0j6Hk =gj+T -----END PGP SIGNATURE----- Merge tag '6.8-rc-smb-server-fixes-part2' of git://git.samba.org/ksmbd Pull more smb server updates from Steve French: - Fix for incorrect oplock break on directories when leases disabled - UAF fix for race between create and destroy of tcp connection - Important session setup SPNEGO fix - Update ksmbd feature status summary * tag '6.8-rc-smb-server-fixes-part2' of git://git.samba.org/ksmbd: ksmbd: only v2 leases handle the directory ksmbd: fix UAF issue in ksmbd_tcp_new_connection() ksmbd: validate mech token in session setup ksmbd: update feature status in documentation
This commit is contained in:
commit
8cb1bb178c
@ -73,15 +73,14 @@ Auto Negotiation Supported.
|
||||
Compound Request Supported.
|
||||
Oplock Cache Mechanism Supported.
|
||||
SMB2 leases(v1 lease) Supported.
|
||||
Directory leases(v2 lease) Planned for future.
|
||||
Directory leases(v2 lease) Supported.
|
||||
Multi-credits Supported.
|
||||
NTLM/NTLMv2 Supported.
|
||||
HMAC-SHA256 Signing Supported.
|
||||
Secure negotiate Supported.
|
||||
Signing Update Supported.
|
||||
Pre-authentication integrity Supported.
|
||||
SMB3 encryption(CCM, GCM) Supported. (CCM and GCM128 supported, GCM256 in
|
||||
progress)
|
||||
SMB3 encryption(CCM, GCM) Supported. (CCM/GCM128 and CCM/GCM256 supported)
|
||||
SMB direct(RDMA) Supported.
|
||||
SMB3 Multi-channel Partially Supported. Planned to implement
|
||||
replay/retry mechanisms for future.
|
||||
@ -112,6 +111,10 @@ DCE/RPC support Partially Supported. a few calls(NetShareEnumAll,
|
||||
for Witness protocol e.g.)
|
||||
ksmbd/nfsd interoperability Planned for future. The features that ksmbd
|
||||
support are Leases, Notify, ACLs and Share modes.
|
||||
SMB3.1.1 Compression Planned for future.
|
||||
SMB3.1.1 over QUIC Planned for future.
|
||||
Signing/Encryption over RDMA Planned for future.
|
||||
SMB3.1.1 GMAC signing support Planned for future.
|
||||
============================== =================================================
|
||||
|
||||
|
||||
|
@ -214,10 +214,15 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen,
|
||||
{
|
||||
struct ksmbd_conn *conn = context;
|
||||
|
||||
if (!vlen)
|
||||
return -EINVAL;
|
||||
|
||||
conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL);
|
||||
if (!conn->mechToken)
|
||||
return -ENOMEM;
|
||||
|
||||
conn->mechTokenLen = (unsigned int)vlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -416,13 +416,7 @@ static void stop_sessions(void)
|
||||
again:
|
||||
down_read(&conn_list_lock);
|
||||
list_for_each_entry(conn, &conn_list, conns_list) {
|
||||
struct task_struct *task;
|
||||
|
||||
t = conn->transport;
|
||||
task = t->handler;
|
||||
if (task)
|
||||
ksmbd_debug(CONN, "Stop session handler %s/%d\n",
|
||||
task->comm, task_pid_nr(task));
|
||||
ksmbd_conn_set_exiting(conn);
|
||||
if (t->ops->shutdown) {
|
||||
up_read(&conn_list_lock);
|
||||
|
@ -88,6 +88,7 @@ struct ksmbd_conn {
|
||||
__u16 dialect;
|
||||
|
||||
char *mechToken;
|
||||
unsigned int mechTokenLen;
|
||||
|
||||
struct ksmbd_conn_ops *conn_ops;
|
||||
|
||||
@ -134,7 +135,6 @@ struct ksmbd_transport_ops {
|
||||
struct ksmbd_transport {
|
||||
struct ksmbd_conn *conn;
|
||||
struct ksmbd_transport_ops *ops;
|
||||
struct task_struct *handler;
|
||||
};
|
||||
|
||||
#define KSMBD_TCP_RECV_TIMEOUT (7 * HZ)
|
||||
|
@ -1197,6 +1197,12 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
|
||||
bool prev_op_has_lease;
|
||||
__le32 prev_op_state = 0;
|
||||
|
||||
/* Only v2 leases handle the directory */
|
||||
if (S_ISDIR(file_inode(fp->filp)->i_mode)) {
|
||||
if (!lctx || lctx->version != 2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
opinfo = alloc_opinfo(work, pid, tid);
|
||||
if (!opinfo)
|
||||
return -ENOMEM;
|
||||
|
@ -1414,7 +1414,10 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
|
||||
char *name;
|
||||
unsigned int name_off, name_len, secbuf_len;
|
||||
|
||||
secbuf_len = le16_to_cpu(req->SecurityBufferLength);
|
||||
if (conn->use_spnego && conn->mechToken)
|
||||
secbuf_len = conn->mechTokenLen;
|
||||
else
|
||||
secbuf_len = le16_to_cpu(req->SecurityBufferLength);
|
||||
if (secbuf_len < sizeof(struct authenticate_message)) {
|
||||
ksmbd_debug(SMB, "blob len %d too small\n", secbuf_len);
|
||||
return NULL;
|
||||
@ -1505,7 +1508,10 @@ static int ntlm_authenticate(struct ksmbd_work *work,
|
||||
struct authenticate_message *authblob;
|
||||
|
||||
authblob = user_authblob(conn, req);
|
||||
sz = le16_to_cpu(req->SecurityBufferLength);
|
||||
if (conn->use_spnego && conn->mechToken)
|
||||
sz = conn->mechTokenLen;
|
||||
else
|
||||
sz = le16_to_cpu(req->SecurityBufferLength);
|
||||
rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess);
|
||||
if (rc) {
|
||||
set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD);
|
||||
@ -1778,8 +1784,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
||||
|
||||
negblob_off = le16_to_cpu(req->SecurityBufferOffset);
|
||||
negblob_len = le16_to_cpu(req->SecurityBufferLength);
|
||||
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) ||
|
||||
negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
|
||||
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer)) {
|
||||
rc = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
@ -1788,8 +1793,15 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
||||
negblob_off);
|
||||
|
||||
if (decode_negotiation_token(conn, negblob, negblob_len) == 0) {
|
||||
if (conn->mechToken)
|
||||
if (conn->mechToken) {
|
||||
negblob = (struct negotiate_message *)conn->mechToken;
|
||||
negblob_len = conn->mechTokenLen;
|
||||
}
|
||||
}
|
||||
|
||||
if (negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
|
||||
rc = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (server_conf.auth_mechs & conn->auth_mechs) {
|
||||
|
@ -2039,6 +2039,7 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs)
|
||||
static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
|
||||
{
|
||||
struct smb_direct_transport *t;
|
||||
struct task_struct *handler;
|
||||
int ret;
|
||||
|
||||
if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) {
|
||||
@ -2056,11 +2057,11 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
|
||||
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
|
||||
smb_direct_port);
|
||||
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
|
||||
ret = PTR_ERR(KSMBD_TRANS(t)->handler);
|
||||
handler = kthread_run(ksmbd_conn_handler_loop,
|
||||
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
|
||||
smb_direct_port);
|
||||
if (IS_ERR(handler)) {
|
||||
ret = PTR_ERR(handler);
|
||||
pr_err("Can't start thread\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
@ -185,6 +185,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
|
||||
struct sockaddr *csin;
|
||||
int rc = 0;
|
||||
struct tcp_transport *t;
|
||||
struct task_struct *handler;
|
||||
|
||||
t = alloc_transport(client_sk);
|
||||
if (!t) {
|
||||
@ -199,13 +200,13 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
|
||||
KSMBD_TRANS(t)->conn,
|
||||
"ksmbd:%u",
|
||||
ksmbd_tcp_get_port(csin));
|
||||
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
|
||||
handler = kthread_run(ksmbd_conn_handler_loop,
|
||||
KSMBD_TRANS(t)->conn,
|
||||
"ksmbd:%u",
|
||||
ksmbd_tcp_get_port(csin));
|
||||
if (IS_ERR(handler)) {
|
||||
pr_err("cannot start conn thread\n");
|
||||
rc = PTR_ERR(KSMBD_TRANS(t)->handler);
|
||||
rc = PTR_ERR(handler);
|
||||
free_transport(t);
|
||||
}
|
||||
return rc;
|
||||
|
Loading…
Reference in New Issue
Block a user