Skip to content

Commit

Permalink
Merge tag '6.8-rc-smb-server-fixes-part2' of git://git.samba.org/ksmbd
Browse files Browse the repository at this point in the history
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
  • Loading branch information
torvalds committed Jan 19, 2024
2 parents 16df6e0 + 77bebd1 commit 8cb1bb1
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 26 deletions.
9 changes: 6 additions & 3 deletions Documentation/filesystems/smb/ksmbd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
============================== =================================================


Expand Down
5 changes: 5 additions & 0 deletions fs/smb/server/asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
6 changes: 0 additions & 6 deletions fs/smb/server/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion fs/smb/server/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ struct ksmbd_conn {
__u16 dialect;

char *mechToken;
unsigned int mechTokenLen;

struct ksmbd_conn_ops *conn_ops;

Expand Down Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions fs/smb/server/oplock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 17 additions & 5 deletions fs/smb/server/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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) {
Expand Down
11 changes: 6 additions & 5 deletions fs/smb/server/transport_rdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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;
}
Expand Down
13 changes: 7 additions & 6 deletions fs/smb/server/transport_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down

0 comments on commit 8cb1bb1

Please sign in to comment.