Skip to content

Commit 8cb1bb1

Browse files
committed
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
2 parents 16df6e0 + 77bebd1 commit 8cb1bb1

File tree

8 files changed

+48
-26
lines changed

8 files changed

+48
-26
lines changed

Documentation/filesystems/smb/ksmbd.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,14 @@ Auto Negotiation Supported.
7373
Compound Request Supported.
7474
Oplock Cache Mechanism Supported.
7575
SMB2 leases(v1 lease) Supported.
76-
Directory leases(v2 lease) Planned for future.
76+
Directory leases(v2 lease) Supported.
7777
Multi-credits Supported.
7878
NTLM/NTLMv2 Supported.
7979
HMAC-SHA256 Signing Supported.
8080
Secure negotiate Supported.
8181
Signing Update Supported.
8282
Pre-authentication integrity Supported.
83-
SMB3 encryption(CCM, GCM) Supported. (CCM and GCM128 supported, GCM256 in
84-
progress)
83+
SMB3 encryption(CCM, GCM) Supported. (CCM/GCM128 and CCM/GCM256 supported)
8584
SMB direct(RDMA) Supported.
8685
SMB3 Multi-channel Partially Supported. Planned to implement
8786
replay/retry mechanisms for future.
@@ -112,6 +111,10 @@ DCE/RPC support Partially Supported. a few calls(NetShareEnumAll,
112111
for Witness protocol e.g.)
113112
ksmbd/nfsd interoperability Planned for future. The features that ksmbd
114113
support are Leases, Notify, ACLs and Share modes.
114+
SMB3.1.1 Compression Planned for future.
115+
SMB3.1.1 over QUIC Planned for future.
116+
Signing/Encryption over RDMA Planned for future.
117+
SMB3.1.1 GMAC signing support Planned for future.
115118
============================== =================================================
116119

117120

fs/smb/server/asn1.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,15 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen,
214214
{
215215
struct ksmbd_conn *conn = context;
216216

217+
if (!vlen)
218+
return -EINVAL;
219+
217220
conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL);
218221
if (!conn->mechToken)
219222
return -ENOMEM;
220223

224+
conn->mechTokenLen = (unsigned int)vlen;
225+
221226
return 0;
222227
}
223228

fs/smb/server/connection.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,7 @@ static void stop_sessions(void)
416416
again:
417417
down_read(&conn_list_lock);
418418
list_for_each_entry(conn, &conn_list, conns_list) {
419-
struct task_struct *task;
420-
421419
t = conn->transport;
422-
task = t->handler;
423-
if (task)
424-
ksmbd_debug(CONN, "Stop session handler %s/%d\n",
425-
task->comm, task_pid_nr(task));
426420
ksmbd_conn_set_exiting(conn);
427421
if (t->ops->shutdown) {
428422
up_read(&conn_list_lock);

fs/smb/server/connection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct ksmbd_conn {
8888
__u16 dialect;
8989

9090
char *mechToken;
91+
unsigned int mechTokenLen;
9192

9293
struct ksmbd_conn_ops *conn_ops;
9394

@@ -134,7 +135,6 @@ struct ksmbd_transport_ops {
134135
struct ksmbd_transport {
135136
struct ksmbd_conn *conn;
136137
struct ksmbd_transport_ops *ops;
137-
struct task_struct *handler;
138138
};
139139

140140
#define KSMBD_TCP_RECV_TIMEOUT (7 * HZ)

fs/smb/server/oplock.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,12 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
11971197
bool prev_op_has_lease;
11981198
__le32 prev_op_state = 0;
11991199

1200+
/* Only v2 leases handle the directory */
1201+
if (S_ISDIR(file_inode(fp->filp)->i_mode)) {
1202+
if (!lctx || lctx->version != 2)
1203+
return 0;
1204+
}
1205+
12001206
opinfo = alloc_opinfo(work, pid, tid);
12011207
if (!opinfo)
12021208
return -ENOMEM;

fs/smb/server/smb2pdu.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,10 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
14141414
char *name;
14151415
unsigned int name_off, name_len, secbuf_len;
14161416

1417-
secbuf_len = le16_to_cpu(req->SecurityBufferLength);
1417+
if (conn->use_spnego && conn->mechToken)
1418+
secbuf_len = conn->mechTokenLen;
1419+
else
1420+
secbuf_len = le16_to_cpu(req->SecurityBufferLength);
14181421
if (secbuf_len < sizeof(struct authenticate_message)) {
14191422
ksmbd_debug(SMB, "blob len %d too small\n", secbuf_len);
14201423
return NULL;
@@ -1505,7 +1508,10 @@ static int ntlm_authenticate(struct ksmbd_work *work,
15051508
struct authenticate_message *authblob;
15061509

15071510
authblob = user_authblob(conn, req);
1508-
sz = le16_to_cpu(req->SecurityBufferLength);
1511+
if (conn->use_spnego && conn->mechToken)
1512+
sz = conn->mechTokenLen;
1513+
else
1514+
sz = le16_to_cpu(req->SecurityBufferLength);
15091515
rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess);
15101516
if (rc) {
15111517
set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD);
@@ -1778,8 +1784,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
17781784

17791785
negblob_off = le16_to_cpu(req->SecurityBufferOffset);
17801786
negblob_len = le16_to_cpu(req->SecurityBufferLength);
1781-
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) ||
1782-
negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
1787+
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer)) {
17831788
rc = -EINVAL;
17841789
goto out_err;
17851790
}
@@ -1788,8 +1793,15 @@ int smb2_sess_setup(struct ksmbd_work *work)
17881793
negblob_off);
17891794

17901795
if (decode_negotiation_token(conn, negblob, negblob_len) == 0) {
1791-
if (conn->mechToken)
1796+
if (conn->mechToken) {
17921797
negblob = (struct negotiate_message *)conn->mechToken;
1798+
negblob_len = conn->mechTokenLen;
1799+
}
1800+
}
1801+
1802+
if (negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
1803+
rc = -EINVAL;
1804+
goto out_err;
17931805
}
17941806

17951807
if (server_conf.auth_mechs & conn->auth_mechs) {

fs/smb/server/transport_rdma.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,7 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs)
20392039
static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
20402040
{
20412041
struct smb_direct_transport *t;
2042+
struct task_struct *handler;
20422043
int ret;
20432044

20442045
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)
20562057
if (ret)
20572058
goto out_err;
20582059

2059-
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
2060-
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
2061-
smb_direct_port);
2062-
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
2063-
ret = PTR_ERR(KSMBD_TRANS(t)->handler);
2060+
handler = kthread_run(ksmbd_conn_handler_loop,
2061+
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
2062+
smb_direct_port);
2063+
if (IS_ERR(handler)) {
2064+
ret = PTR_ERR(handler);
20642065
pr_err("Can't start thread\n");
20652066
goto out_err;
20662067
}

fs/smb/server/transport_tcp.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
185185
struct sockaddr *csin;
186186
int rc = 0;
187187
struct tcp_transport *t;
188+
struct task_struct *handler;
188189

189190
t = alloc_transport(client_sk);
190191
if (!t) {
@@ -199,13 +200,13 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
199200
goto out_error;
200201
}
201202

202-
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
203-
KSMBD_TRANS(t)->conn,
204-
"ksmbd:%u",
205-
ksmbd_tcp_get_port(csin));
206-
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
203+
handler = kthread_run(ksmbd_conn_handler_loop,
204+
KSMBD_TRANS(t)->conn,
205+
"ksmbd:%u",
206+
ksmbd_tcp_get_port(csin));
207+
if (IS_ERR(handler)) {
207208
pr_err("cannot start conn thread\n");
208-
rc = PTR_ERR(KSMBD_TRANS(t)->handler);
209+
rc = PTR_ERR(handler);
209210
free_transport(t);
210211
}
211212
return rc;

0 commit comments

Comments
 (0)