4 smb3 server fixes, all also for stable
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmPRylYACgkQiiy9cAdy T1H8mwwAtCAURtWHarVx1x0yvwBVKEM2x5h3wdXR4OnJvYddXr7AcdcB3rLKWRGp aRH865jnIv9M4LtxJ1Ap/sLaAD0885YdkfQPYLV/tJluvk5L2soZiqvAzclY7Q81 Fgrvl4PjE5msqQGWw4ubyk7cxAxqINnxXUXHNpYICgksX4gUE1tJe6UraLoVBPPR D254ifviUKZIeOT9RmuunayNC3DwCnAqCUVoZ7OyZrIecM80jQiWApyiz5J/H3m7 FdCoOKdOKT9rTI5Fc7Nutzk8pvW9iyb32K4rGXUeaun/JtdYEUdQkWQr32LgBJ4C rOzDkSMGqQM8TOUST3wuPDTSEcSzTgrJHYw/tPmKt6yS+zFHDozV8m9b7g7GG3kM +nFyRKSBr/wiqBIzwDnQnvocu1o0KWjAVXba+KYs3X2TWL9YQ33V7qObZVSC5xa0 84scfHZD0Lie5XxwxuRlPjV41xXEaXA0/5JSIvdSPFLVlYDXIdnk4FZOwSVWOR0y JoeX5Vw0 =AHfk -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
2543fdbd5c
|
@ -280,7 +280,7 @@ int ksmbd_conn_handler_loop(void *p)
|
|||
{
|
||||
struct ksmbd_conn *conn = (struct ksmbd_conn *)p;
|
||||
struct ksmbd_transport *t = conn->transport;
|
||||
unsigned int pdu_size;
|
||||
unsigned int pdu_size, max_allowed_pdu_size;
|
||||
char hdr_buf[4] = {0,};
|
||||
int size;
|
||||
|
||||
|
@ -305,13 +305,26 @@ int ksmbd_conn_handler_loop(void *p)
|
|||
pdu_size = get_rfc1002_len(hdr_buf);
|
||||
ksmbd_debug(CONN, "RFC1002 header %u bytes\n", pdu_size);
|
||||
|
||||
if (conn->status == KSMBD_SESS_GOOD)
|
||||
max_allowed_pdu_size =
|
||||
SMB3_MAX_MSGSIZE + conn->vals->max_write_size;
|
||||
else
|
||||
max_allowed_pdu_size = SMB3_MAX_MSGSIZE;
|
||||
|
||||
if (pdu_size > max_allowed_pdu_size) {
|
||||
pr_err_ratelimited("PDU length(%u) excceed maximum allowed pdu size(%u) on connection(%d)\n",
|
||||
pdu_size, max_allowed_pdu_size,
|
||||
conn->status);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if pdu size is valid (min : smb header size,
|
||||
* max : 0x00FFFFFF).
|
||||
*/
|
||||
if (pdu_size < __SMB2_HEADER_STRUCTURE_SIZE ||
|
||||
pdu_size > MAX_STREAM_PROT_LEN) {
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 4 for rfc1002 length field */
|
||||
|
|
|
@ -106,7 +106,8 @@ struct ksmbd_startup_request {
|
|||
__u32 sub_auth[3]; /* Subauth value for Security ID */
|
||||
__u32 smb2_max_credits; /* MAX credits */
|
||||
__u32 smbd_max_io_size; /* smbd read write size */
|
||||
__u32 reserved[127]; /* Reserved room */
|
||||
__u32 max_connections; /* Number of maximum simultaneous connections */
|
||||
__u32 reserved[126]; /* Reserved room */
|
||||
__u32 ifc_list_sz; /* interfaces list size */
|
||||
__s8 ____payload[];
|
||||
};
|
||||
|
|
|
@ -242,7 +242,7 @@ int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
|
|||
return ret;
|
||||
|
||||
if (da->version != 3 && da->version != 4) {
|
||||
pr_err("v%d version is not supported\n", da->version);
|
||||
ksmbd_debug(VFS, "v%d version is not supported\n", da->version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
|
|||
return ret;
|
||||
|
||||
if (da->version != version2) {
|
||||
pr_err("ndr version mismatched(version: %d, version2: %d)\n",
|
||||
ksmbd_debug(VFS, "ndr version mismatched(version: %d, version2: %d)\n",
|
||||
da->version, version2);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -457,7 +457,7 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl)
|
|||
if (ret)
|
||||
return ret;
|
||||
if (acl->version != 4) {
|
||||
pr_err("v%d version is not supported\n", acl->version);
|
||||
ksmbd_debug(VFS, "v%d version is not supported\n", acl->version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,7 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl)
|
|||
if (ret)
|
||||
return ret;
|
||||
if (acl->version != version2) {
|
||||
pr_err("ndr version mismatched(version: %d, version2: %d)\n",
|
||||
ksmbd_debug(VFS, "ndr version mismatched(version: %d, version2: %d)\n",
|
||||
acl->version, version2);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ struct ksmbd_server_config {
|
|||
unsigned int share_fake_fscaps;
|
||||
struct smb_sid domain_sid;
|
||||
unsigned int auth_mechs;
|
||||
unsigned int max_connections;
|
||||
|
||||
char *conf[SERVER_CONF_WORK_GROUP + 1];
|
||||
};
|
||||
|
|
|
@ -8663,6 +8663,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
|
|||
bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
|
||||
{
|
||||
struct ksmbd_conn *conn = work->conn;
|
||||
struct ksmbd_session *sess = work->sess;
|
||||
struct smb2_hdr *rsp = smb2_get_msg(work->response_buf);
|
||||
|
||||
if (conn->dialect < SMB30_PROT_ID)
|
||||
|
@ -8672,6 +8673,7 @@ bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
|
|||
rsp = ksmbd_resp_buf_next(work);
|
||||
|
||||
if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
|
||||
sess->user && !user_guest(sess->user) &&
|
||||
rsp->Status == STATUS_SUCCESS)
|
||||
return true;
|
||||
return false;
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
#define SMB21_DEFAULT_IOSIZE (1024 * 1024)
|
||||
#define SMB3_DEFAULT_TRANS_SIZE (1024 * 1024)
|
||||
#define SMB3_MIN_IOSIZE (64 * 1024)
|
||||
#define SMB3_MAX_IOSIZE (8 * 1024 * 1024)
|
||||
#define SMB3_MIN_IOSIZE (64 * 1024)
|
||||
#define SMB3_MAX_IOSIZE (8 * 1024 * 1024)
|
||||
#define SMB3_MAX_MSGSIZE (4 * 4096)
|
||||
|
||||
/*
|
||||
* Definitions for SMB2 Protocol Data Units (network frames)
|
||||
|
|
|
@ -308,6 +308,9 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
|
|||
if (req->smbd_max_io_size)
|
||||
init_smbd_max_io_size(req->smbd_max_io_size);
|
||||
|
||||
if (req->max_connections)
|
||||
server_conf.max_connections = req->max_connections;
|
||||
|
||||
ret = ksmbd_set_netbios_name(req->netbios_name);
|
||||
ret |= ksmbd_set_server_string(req->server_string);
|
||||
ret |= ksmbd_set_work_group(req->work_group);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#define IFACE_STATE_DOWN BIT(0)
|
||||
#define IFACE_STATE_CONFIGURED BIT(1)
|
||||
|
||||
static atomic_t active_num_conn;
|
||||
|
||||
struct interface {
|
||||
struct task_struct *ksmbd_kthread;
|
||||
struct socket *ksmbd_socket;
|
||||
|
@ -185,8 +187,10 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
|
|||
struct tcp_transport *t;
|
||||
|
||||
t = alloc_transport(client_sk);
|
||||
if (!t)
|
||||
if (!t) {
|
||||
sock_release(client_sk);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
csin = KSMBD_TCP_PEER_SOCKADDR(KSMBD_TRANS(t)->conn);
|
||||
if (kernel_getpeername(client_sk, csin) < 0) {
|
||||
|
@ -239,6 +243,15 @@ static int ksmbd_kthread_fn(void *p)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (server_conf.max_connections &&
|
||||
atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {
|
||||
pr_info_ratelimited("Limit the maximum number of connections(%u)\n",
|
||||
atomic_read(&active_num_conn));
|
||||
atomic_dec(&active_num_conn);
|
||||
sock_release(client_sk);
|
||||
continue;
|
||||
}
|
||||
|
||||
ksmbd_debug(CONN, "connect success: accepted new connection\n");
|
||||
client_sk->sk->sk_rcvtimeo = KSMBD_TCP_RECV_TIMEOUT;
|
||||
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,
|
|||
static void ksmbd_tcp_disconnect(struct ksmbd_transport *t)
|
||||
{
|
||||
free_transport(TCP_TRANS(t));
|
||||
if (server_conf.max_connections)
|
||||
atomic_dec(&active_num_conn);
|
||||
}
|
||||
|
||||
static void tcp_destroy_socket(struct socket *ksmbd_socket)
|
||||
|
|
Loading…
Reference in New Issue