Skip to content

Commit 2543fdb

Browse files
committed
Merge tag '6.2-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd
Pull ksmbd server fixes from Steve French: "Four smb3 server fixes, all also for stable: - fix for signing bug - fix to more strictly check packet length - add a max connections parm to limit simultaneous connections - fix error message flood that can occur with newer Samba xattr format" * tag '6.2-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd: ksmbd: downgrade ndr version error message to debug ksmbd: limit pdu length size according to connection status ksmbd: do not sign response to session request for guest login ksmbd: add max connections parameter
2 parents 5af6ce7 + a34dc4a commit 2543fdb

File tree

8 files changed

+46
-10
lines changed

8 files changed

+46
-10
lines changed

fs/ksmbd/connection.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ int ksmbd_conn_handler_loop(void *p)
280280
{
281281
struct ksmbd_conn *conn = (struct ksmbd_conn *)p;
282282
struct ksmbd_transport *t = conn->transport;
283-
unsigned int pdu_size;
283+
unsigned int pdu_size, max_allowed_pdu_size;
284284
char hdr_buf[4] = {0,};
285285
int size;
286286

@@ -305,13 +305,26 @@ int ksmbd_conn_handler_loop(void *p)
305305
pdu_size = get_rfc1002_len(hdr_buf);
306306
ksmbd_debug(CONN, "RFC1002 header %u bytes\n", pdu_size);
307307

308+
if (conn->status == KSMBD_SESS_GOOD)
309+
max_allowed_pdu_size =
310+
SMB3_MAX_MSGSIZE + conn->vals->max_write_size;
311+
else
312+
max_allowed_pdu_size = SMB3_MAX_MSGSIZE;
313+
314+
if (pdu_size > max_allowed_pdu_size) {
315+
pr_err_ratelimited("PDU length(%u) excceed maximum allowed pdu size(%u) on connection(%d)\n",
316+
pdu_size, max_allowed_pdu_size,
317+
conn->status);
318+
break;
319+
}
320+
308321
/*
309322
* Check if pdu size is valid (min : smb header size,
310323
* max : 0x00FFFFFF).
311324
*/
312325
if (pdu_size < __SMB2_HEADER_STRUCTURE_SIZE ||
313326
pdu_size > MAX_STREAM_PROT_LEN) {
314-
continue;
327+
break;
315328
}
316329

317330
/* 4 for rfc1002 length field */

fs/ksmbd/ksmbd_netlink.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ struct ksmbd_startup_request {
106106
__u32 sub_auth[3]; /* Subauth value for Security ID */
107107
__u32 smb2_max_credits; /* MAX credits */
108108
__u32 smbd_max_io_size; /* smbd read write size */
109-
__u32 reserved[127]; /* Reserved room */
109+
__u32 max_connections; /* Number of maximum simultaneous connections */
110+
__u32 reserved[126]; /* Reserved room */
110111
__u32 ifc_list_sz; /* interfaces list size */
111112
__s8 ____payload[];
112113
};

fs/ksmbd/ndr.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
242242
return ret;
243243

244244
if (da->version != 3 && da->version != 4) {
245-
pr_err("v%d version is not supported\n", da->version);
245+
ksmbd_debug(VFS, "v%d version is not supported\n", da->version);
246246
return -EINVAL;
247247
}
248248

@@ -251,7 +251,7 @@ int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
251251
return ret;
252252

253253
if (da->version != version2) {
254-
pr_err("ndr version mismatched(version: %d, version2: %d)\n",
254+
ksmbd_debug(VFS, "ndr version mismatched(version: %d, version2: %d)\n",
255255
da->version, version2);
256256
return -EINVAL;
257257
}
@@ -457,15 +457,15 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl)
457457
if (ret)
458458
return ret;
459459
if (acl->version != 4) {
460-
pr_err("v%d version is not supported\n", acl->version);
460+
ksmbd_debug(VFS, "v%d version is not supported\n", acl->version);
461461
return -EINVAL;
462462
}
463463

464464
ret = ndr_read_int32(n, &version2);
465465
if (ret)
466466
return ret;
467467
if (acl->version != version2) {
468-
pr_err("ndr version mismatched(version: %d, version2: %d)\n",
468+
ksmbd_debug(VFS, "ndr version mismatched(version: %d, version2: %d)\n",
469469
acl->version, version2);
470470
return -EINVAL;
471471
}

fs/ksmbd/server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct ksmbd_server_config {
4141
unsigned int share_fake_fscaps;
4242
struct smb_sid domain_sid;
4343
unsigned int auth_mechs;
44+
unsigned int max_connections;
4445

4546
char *conf[SERVER_CONF_WORK_GROUP + 1];
4647
};

fs/ksmbd/smb2pdu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8663,6 +8663,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
86638663
bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
86648664
{
86658665
struct ksmbd_conn *conn = work->conn;
8666+
struct ksmbd_session *sess = work->sess;
86668667
struct smb2_hdr *rsp = smb2_get_msg(work->response_buf);
86678668

86688669
if (conn->dialect < SMB30_PROT_ID)
@@ -8672,6 +8673,7 @@ bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
86728673
rsp = ksmbd_resp_buf_next(work);
86738674

86748675
if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
8676+
sess->user && !user_guest(sess->user) &&
86758677
rsp->Status == STATUS_SUCCESS)
86768678
return true;
86778679
return false;

fs/ksmbd/smb2pdu.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424

2525
#define SMB21_DEFAULT_IOSIZE (1024 * 1024)
2626
#define SMB3_DEFAULT_TRANS_SIZE (1024 * 1024)
27-
#define SMB3_MIN_IOSIZE (64 * 1024)
28-
#define SMB3_MAX_IOSIZE (8 * 1024 * 1024)
27+
#define SMB3_MIN_IOSIZE (64 * 1024)
28+
#define SMB3_MAX_IOSIZE (8 * 1024 * 1024)
29+
#define SMB3_MAX_MSGSIZE (4 * 4096)
2930

3031
/*
3132
* Definitions for SMB2 Protocol Data Units (network frames)

fs/ksmbd/transport_ipc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
308308
if (req->smbd_max_io_size)
309309
init_smbd_max_io_size(req->smbd_max_io_size);
310310

311+
if (req->max_connections)
312+
server_conf.max_connections = req->max_connections;
313+
311314
ret = ksmbd_set_netbios_name(req->netbios_name);
312315
ret |= ksmbd_set_server_string(req->server_string);
313316
ret |= ksmbd_set_work_group(req->work_group);

fs/ksmbd/transport_tcp.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#define IFACE_STATE_DOWN BIT(0)
1616
#define IFACE_STATE_CONFIGURED BIT(1)
1717

18+
static atomic_t active_num_conn;
19+
1820
struct interface {
1921
struct task_struct *ksmbd_kthread;
2022
struct socket *ksmbd_socket;
@@ -185,8 +187,10 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
185187
struct tcp_transport *t;
186188

187189
t = alloc_transport(client_sk);
188-
if (!t)
190+
if (!t) {
191+
sock_release(client_sk);
189192
return -ENOMEM;
193+
}
190194

191195
csin = KSMBD_TCP_PEER_SOCKADDR(KSMBD_TRANS(t)->conn);
192196
if (kernel_getpeername(client_sk, csin) < 0) {
@@ -239,6 +243,15 @@ static int ksmbd_kthread_fn(void *p)
239243
continue;
240244
}
241245

246+
if (server_conf.max_connections &&
247+
atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {
248+
pr_info_ratelimited("Limit the maximum number of connections(%u)\n",
249+
atomic_read(&active_num_conn));
250+
atomic_dec(&active_num_conn);
251+
sock_release(client_sk);
252+
continue;
253+
}
254+
242255
ksmbd_debug(CONN, "connect success: accepted new connection\n");
243256
client_sk->sk->sk_rcvtimeo = KSMBD_TCP_RECV_TIMEOUT;
244257
client_sk->sk->sk_sndtimeo = KSMBD_TCP_SEND_TIMEOUT;
@@ -368,6 +381,8 @@ static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,
368381
static void ksmbd_tcp_disconnect(struct ksmbd_transport *t)
369382
{
370383
free_transport(TCP_TRANS(t));
384+
if (server_conf.max_connections)
385+
atomic_dec(&active_num_conn);
371386
}
372387

373388
static void tcp_destroy_socket(struct socket *ksmbd_socket)

0 commit comments

Comments
 (0)