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

Merge tag 'v6.19-rc-smb-fixes' of git://git.samba.org/ksmbd

Pull smb client and server updates from Steve French:

 - server fixes:
     - IPC use after free locking fix
     - fix locking bug in delete paths
     - fix use after free in disconnect
     - fix underflow in locking check
     - error mapping improvement
     - socket listening improvement
     - return code mapping fixes
     - crypto improvements (use default libraries)

 - cleanup patches:
     - netfs
     - client checkpatch cleanup
     - server cleanup
     - move server/client duplicate code to common code
     - fix some defines to better match protocol specification

  - smbdirect (RDMA) fixes

  - client debugging improvements for leases

* tag 'v6.19-rc-smb-fixes' of git://git.samba.org/ksmbd: (44 commits)
  cifs: Use netfs_alloc/free_folioq_buffer()
  smb: client: show smb lease key in open_dirs output
  smb: client: show smb lease key in open_files output
  ksmbd: ipc: fix use-after-free in ipc_msg_send_request
  smb: client: relax WARN_ON_ONCE(SMBDIRECT_SOCKET_*) checks in recv_done() and smbd_conn_upcall()
  smb: server: relax WARN_ON_ONCE(SMBDIRECT_SOCKET_*) checks in recv_done() and smb_direct_cm_handler()
  smb: smbdirect: introduce SMBDIRECT_CHECK_STATUS_{WARN,DISCONNECT}()
  smb: smbdirect: introduce SMBDIRECT_DEBUG_ERR_PTR() helper
  ksmbd: vfs: fix race on m_flags in vfs_cache
  ksmbd: Replace strcpy + strcat to improve convert_to_nt_pathname
  smb: move FILE_SYSTEM_ATTRIBUTE_INFO to common/fscc.h
  ksmbd: implement error handling for STATUS_INFO_LENGTH_MISMATCH in smb server
  ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency
  ksmbd: server: avoid busy polling in accept loop
  smb: move create_durable_reconn to common/smb2pdu.h
  smb: fix some warnings reported by scripts/checkpatch.pl
  smb: do some cleanups
  smb: move FILE_SYSTEM_SIZE_INFO to common/fscc.h
  smb: move some duplicate struct definitions to common/fscc.h
  smb: move list of FileSystemAttributes to common/fscc.h
  ...
parents 3ed1c683 e1469f56
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -249,9 +249,9 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
	seq_puts(m, "# Format:\n");
	seq_puts(m, "# <tree id> <ses id> <persistent fid> <flags> <count> <pid> <uid>");
#ifdef CONFIG_CIFS_DEBUG2
	seq_puts(m, " <filename> <lease> <mid>\n");
	seq_puts(m, " <filename> <lease> <lease-key> <mid>\n");
#else
	seq_puts(m, " <filename> <lease>\n");
	seq_puts(m, " <filename> <lease> <lease-key>\n");
#endif /* CIFS_DEBUG2 */
	spin_lock(&cifs_tcp_ses_lock);
	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
@@ -274,6 +274,7 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)

					/* Append lease/oplock caching state as RHW letters */
					inode = d_inode(cfile->dentry);
					cinode = NULL;
					n = 0;
					if (inode) {
						cinode = CIFS_I(inode);
@@ -291,6 +292,12 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
					else
						seq_puts(m, "NONE");

					seq_puts(m, " ");
					if (cinode && cinode->lease_granted)
						seq_printf(m, "%pUl", cinode->lease_key);
					else
						seq_puts(m, "-");

#ifdef CONFIG_CIFS_DEBUG2
					seq_printf(m, " %llu", cfile->fid.mid);
#endif /* CONFIG_CIFS_DEBUG2 */
@@ -317,7 +324,7 @@ static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v)

	seq_puts(m, "# Version:1\n");
	seq_puts(m, "# Format:\n");
	seq_puts(m, "# <tree id> <sess id> <persistent fid> <path>\n");
	seq_puts(m, "# <tree id> <sess id> <persistent fid> <lease-key> <path>\n");

	spin_lock(&cifs_tcp_ses_lock);
	list_for_each(stmp, &cifs_tcp_ses_list) {
@@ -336,11 +343,15 @@ static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v)
						(unsigned long)atomic_long_read(&cfids->total_dirents_entries),
						(unsigned long long)atomic64_read(&cfids->total_dirents_bytes));
				list_for_each_entry(cfid, &cfids->entries, entry) {
					seq_printf(m, "0x%x 0x%llx 0x%llx     %s",
					seq_printf(m, "0x%x 0x%llx 0x%llx ",
						tcon->tid,
						ses->Suid,
						cfid->fid.persistent_fid,
						cfid->path);
						cfid->fid.persistent_fid);
					if (cfid->has_lease)
						seq_printf(m, "%pUl ", cfid->fid.lease_key);
					else
						seq_puts(m, "- ");
					seq_printf(m, "%s", cfid->path);
					if (cfid->file_all_info_is_valid)
						seq_printf(m, "\tvalid file info");
					if (cfid->dirents.is_valid)
+2 −29
Original line number Diff line number Diff line
@@ -24,8 +24,9 @@
#include "cifsacl.h"
#include <crypto/internal/hash.h>
#include <uapi/linux/cifs/cifs_mount.h>
#include "../common/cifsglob.h"
#include "../common/smbglob.h"
#include "../common/smb2pdu.h"
#include "../common/fscc.h"
#include "smb2pdu.h"
#include <linux/filelock.h>

@@ -633,28 +634,6 @@ struct smb_version_operations {
					       struct kvec *xattr_iov);
};

struct smb_version_values {
	char		*version_string;
	__u16		protocol_id;
	__u32		req_capabilities;
	__u32		large_lock_type;
	__u32		exclusive_lock_type;
	__u32		shared_lock_type;
	__u32		unlock_lock_type;
	size_t		header_preamble_size;
	size_t		header_size;
	size_t		max_header_size;
	size_t		read_rsp_size;
	__le16		lock_cmd;
	unsigned int	cap_unix;
	unsigned int	cap_nt_find;
	unsigned int	cap_large_files;
	unsigned int	cap_unicode;
	__u16		signing_enabled;
	__u16		signing_required;
	size_t		create_lease_size;
};

#define HEADER_SIZE(server) (server->vals->header_size)
#define MAX_HEADER_SIZE(server) (server->vals->max_header_size)
#define HEADER_PREAMBLE_SIZE(server) (server->vals->header_preamble_size)
@@ -692,12 +671,6 @@ struct cifs_mnt_data {
	int flags;
};

static inline unsigned int
get_rfc1002_length(void *buf)
{
	return be32_to_cpu(*((__be32 *)buf)) & 0xffffff;
}

struct TCP_Server_Info {
	struct list_head tcp_ses_list;
	struct list_head smb_ses_list;
+166 −435

File changed.

Preview size limit exceeded, changes collapsed.

+9 −9
Original line number Diff line number Diff line
@@ -361,7 +361,7 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
}

static int
decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
decode_ext_sec_blob(struct cifs_ses *ses, SMB_NEGOTIATE_RSP *pSMBr)
{
	int	rc = 0;
	u16	count;
@@ -419,8 +419,8 @@ CIFSSMBNegotiate(const unsigned int xid,
		 struct cifs_ses *ses,
		 struct TCP_Server_Info *server)
{
	NEGOTIATE_REQ *pSMB;
	NEGOTIATE_RSP *pSMBr;
	SMB_NEGOTIATE_REQ *pSMB;
	SMB_NEGOTIATE_RSP *pSMBr;
	int rc = 0;
	int bytes_returned;
	int i;
@@ -614,7 +614,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)

	iov[0].iov_len = 4;
	iov[0].iov_base = smb;
	iov[1].iov_len = get_rfc1002_length(smb);
	iov[1].iov_len = get_rfc1002_len(smb);
	iov[1].iov_base = (char *)smb + 4;

	rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
@@ -1458,7 +1458,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
	rdata->iov[0].iov_base = smb;
	rdata->iov[0].iov_len = 4;
	rdata->iov[1].iov_base = (char *)smb + 4;
	rdata->iov[1].iov_len = get_rfc1002_length(smb);
	rdata->iov[1].iov_len = get_rfc1002_len(smb);

	trace_smb3_read_enter(rdata->rreq->debug_id,
			      rdata->subreq.debug_index,
@@ -1830,7 +1830,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
	/* 4 for RFC1001 length + 1 for BCC */
	iov[0].iov_len = 4;
	iov[0].iov_base = smb;
	iov[1].iov_len = get_rfc1002_length(smb) + 1;
	iov[1].iov_len = get_rfc1002_len(smb) + 1;
	iov[1].iov_base = (char *)smb + 4;

	rqst.rq_iov = iov;
@@ -4746,7 +4746,7 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
	TRANSACTION2_QFSI_REQ *pSMB = NULL;
	TRANSACTION2_QFSI_RSP *pSMBr = NULL;
	FILE_SYSTEM_INFO *response_data;
	FILE_SYSTEM_SIZE_INFO *response_data;
	int rc = 0;
	int bytes_returned = 0;
	__u16 params, byte_count;
@@ -4794,7 +4794,7 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);

			response_data =
			    (FILE_SYSTEM_INFO
			    (FILE_SYSTEM_SIZE_INFO
			     *) (((char *) &pSMBr->hdr.Protocol) +
				 data_offset);
			FSData->f_bsize =
@@ -4811,7 +4811,7 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
			FSData->f_blocks =
			    le64_to_cpu(response_data->TotalAllocationUnits);
			FSData->f_bfree = FSData->f_bavail =
			    le64_to_cpu(response_data->FreeAllocationUnits);
			    le64_to_cpu(response_data->AvailableAllocationUnits);
			cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
				 (unsigned long long)FSData->f_blocks,
				 (unsigned long long)FSData->f_bfree,
+4 −4
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
	int resp_buf_type;

	iov[0].iov_base = in_buf;
	iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
	iov[0].iov_len = get_rfc1002_len(in_buf) + 4;
	flags |= CIFS_NO_RSP_BUF;
	rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
	cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
@@ -177,7 +177,7 @@ int
cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
		   bool log_error)
{
	unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
	unsigned int len = get_rfc1002_len(mid->resp_buf) + 4;

	dump_smb(mid->resp_buf, min_t(u32, 92, len));

@@ -370,7 +370,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
		goto out;
	}

	*pbytes_returned = get_rfc1002_length(midQ->resp_buf);
	*pbytes_returned = get_rfc1002_len(midQ->resp_buf);
	memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
	rc = cifs_check_receive(midQ, server, 0);
out:
@@ -554,7 +554,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
		goto out;
	}

	*pbytes_returned = get_rfc1002_length(midQ->resp_buf);
	*pbytes_returned = get_rfc1002_len(midQ->resp_buf);
	memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
	rc = cifs_check_receive(midQ, server, 0);
out:
Loading