Commit c460e789 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '5.15-rc6-ksmbd-fixes' of git://git.samba.org/ksmbd

Pull ksmbd fixes from Steve French:
 "Ten fixes for the ksmbd kernel server, for improved security and
  additional buffer overflow checks:

   - a security improvement to session establishment to reduce the
     possibility of dictionary attacks

   - fix to ensure that maximum i/o size negotiated in the protocol is
     not less than 64K and not more than 8MB to better match expected
     behavior

   - fix for crediting (flow control) important to properly verify that
     sufficient credits are available for the requested operation

   - seven additional buffer overflow, buffer validation checks"

* tag '5.15-rc6-ksmbd-fixes' of git://git.samba.org/ksmbd:
  ksmbd: add buffer validation in session setup
  ksmbd: throttle session setup failures to avoid dictionary attacks
  ksmbd: validate OutputBufferLength of QUERY_DIR, QUERY_INFO, IOCTL requests
  ksmbd: validate credit charge after validating SMB2 PDU body size
  ksmbd: add buffer validation for smb direct
  ksmbd: limit read/write/trans buffer size not to exceed 8MB
  ksmbd: validate compound response buffer
  ksmbd: fix potencial 32bit overflow from data area check in smb2_write
  ksmbd: improve credits management
  ksmbd: add validation in smb2_ioctl
parents 0f386a60 0d994cd4
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -298,8 +298,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
				   int blob_len, struct ksmbd_session *sess)
{
	char *domain_name;
	unsigned int lm_off, nt_off;
	unsigned short nt_len;
	unsigned int nt_off, dn_off;
	unsigned short nt_len, dn_len;
	int ret;

	if (blob_len < sizeof(struct authenticate_message)) {
@@ -314,15 +314,17 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
		return -EINVAL;
	}

	lm_off = le32_to_cpu(authblob->LmChallengeResponse.BufferOffset);
	nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
	nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
	dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
	dn_len = le16_to_cpu(authblob->DomainName.Length);

	if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len)
		return -EINVAL;

	/* TODO : use domain name that imported from configuration file */
	domain_name = smb_strndup_from_utf16((const char *)authblob +
			le32_to_cpu(authblob->DomainName.BufferOffset),
			le16_to_cpu(authblob->DomainName.Length), true,
			sess->conn->local_nls);
	domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
					     dn_len, true, sess->conn->local_nls);
	if (IS_ERR(domain_name))
		return PTR_ERR(domain_name);

+2 −0
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
		conn->local_nls = load_nls_default();
	atomic_set(&conn->req_running, 0);
	atomic_set(&conn->r_count, 0);
	conn->total_credits = 1;

	init_waitqueue_head(&conn->req_running_q);
	INIT_LIST_HEAD(&conn->conns_list);
	INIT_LIST_HEAD(&conn->sessions);
+2 −0
Original line number Diff line number Diff line
@@ -211,6 +211,7 @@ struct ksmbd_tree_disconnect_request {
 */
struct ksmbd_logout_request {
	__s8	account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */
	__u32	account_flags;
};

/*
@@ -317,6 +318,7 @@ enum KSMBD_TREE_CONN_STATUS {
#define KSMBD_USER_FLAG_BAD_UID		BIT(2)
#define KSMBD_USER_FLAG_BAD_USER	BIT(3)
#define KSMBD_USER_FLAG_GUEST_ACCOUNT	BIT(4)
#define KSMBD_USER_FLAG_DELAY_SESSION	BIT(5)

/*
 * Share config flags.
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp)

void ksmbd_free_user(struct ksmbd_user *user)
{
	ksmbd_ipc_logout_request(user->name);
	ksmbd_ipc_logout_request(user->name, user->flags);
	kfree(user->name);
	kfree(user->passkey);
	kfree(user);
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ struct ksmbd_user {

	size_t			passkey_sz;
	char			*passkey;
	unsigned int		failed_login_count;
};

static inline bool user_guest(struct ksmbd_user *user)
Loading