Commit 2543fdbd authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 5af6ce70 a34dc4a9
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -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 */
+2 −1
Original line number Diff line number Diff line
@@ -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[];
};
+4 −4
Original line number Diff line number Diff line
@@ -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;
	}
+1 −0
Original line number Diff line number Diff line
@@ -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];
};
+2 −0
Original line number Diff line number Diff line
@@ -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;
Loading