lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250806203705.2560493-30-dhowells@redhat.com>
Date: Wed,  6 Aug 2025 21:36:50 +0100
From: David Howells <dhowells@...hat.com>
To: Steve French <sfrench@...ba.org>
Cc: David Howells <dhowells@...hat.com>,
	Paulo Alcantara <pc@...guebit.org>,
	Shyam Prasad N <sprasad@...rosoft.com>,
	Tom Talpey <tom@...pey.com>,
	Wang Zhaolong <wangzhaolong@...weicloud.com>,
	Stefan Metzmacher <metze@...ba.org>,
	Mina Almasry <almasrymina@...gle.com>,
	linux-cifs@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	netfs@...ts.linux.dev,
	linux-fsdevel@...r.kernel.org
Subject: [RFC PATCH 29/31] cifs: Rearrange Create request subfuncs

Signed-off-by: David Howells <dhowells@...hat.com>
cc: Steve French <sfrench@...ba.org>
cc: Paulo Alcantara <pc@...guebit.org>
cc: Shyam Prasad N <sprasad@...rosoft.com>
cc: Tom Talpey <tom@...pey.com>
cc: linux-cifs@...r.kernel.org
cc: netfs@...ts.linux.dev
cc: linux-fsdevel@...r.kernel.org
---
 fs/smb/client/smb2pdu.c | 357 ++++++++++++++++++++--------------------
 1 file changed, 178 insertions(+), 179 deletions(-)

diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 9357c4953d9f..85486748dd7b 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -1228,61 +1228,6 @@ static int smb311_decode_neg_context(struct smb_message *smb,
 	return rc;
 }
 
-static struct create_posix *
-create_posix_buf(umode_t mode)
-{
-	struct create_posix *buf;
-
-	buf = kzalloc(sizeof(struct create_posix),
-			GFP_KERNEL);
-	if (!buf)
-		return NULL;
-
-	buf->ccontext.DataOffset =
-		cpu_to_le16(offsetof(struct create_posix, Mode));
-	buf->ccontext.DataLength = cpu_to_le32(4);
-	buf->ccontext.NameOffset =
-		cpu_to_le16(offsetof(struct create_posix, Name));
-	buf->ccontext.NameLength = cpu_to_le16(16);
-
-	/* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
-	buf->Name[0] = 0x93;
-	buf->Name[1] = 0xAD;
-	buf->Name[2] = 0x25;
-	buf->Name[3] = 0x50;
-	buf->Name[4] = 0x9C;
-	buf->Name[5] = 0xB4;
-	buf->Name[6] = 0x11;
-	buf->Name[7] = 0xE7;
-	buf->Name[8] = 0xB4;
-	buf->Name[9] = 0x23;
-	buf->Name[10] = 0x83;
-	buf->Name[11] = 0xDE;
-	buf->Name[12] = 0x96;
-	buf->Name[13] = 0x8B;
-	buf->Name[14] = 0xCD;
-	buf->Name[15] = 0x7C;
-	buf->Mode = cpu_to_le32(mode);
-	cifs_dbg(FYI, "mode on posix create 0%o\n", mode);
-	return buf;
-}
-
-static int
-add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
-{
-	unsigned int num = *num_iovec;
-
-	iov[num].iov_base = create_posix_buf(mode);
-	if (mode == ACL_NO_MODE)
-		cifs_dbg(FYI, "%s: no mode\n", __func__);
-	if (iov[num].iov_base == NULL)
-		return -ENOMEM;
-	iov[num].iov_len = sizeof(struct create_posix);
-	*num_iovec = num + 1;
-	return 0;
-}
-
-
 /*
  *
  *	SMB2 Worker functions follow:
@@ -2443,6 +2388,60 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
 }
 
 
+static struct create_posix *
+create_posix_buf(umode_t mode)
+{
+	struct create_posix *buf;
+
+	buf = kzalloc(sizeof(struct create_posix),
+			GFP_KERNEL);
+	if (!buf)
+		return NULL;
+
+	buf->ccontext.DataOffset =
+		cpu_to_le16(offsetof(struct create_posix, Mode));
+	buf->ccontext.DataLength = cpu_to_le32(4);
+	buf->ccontext.NameOffset =
+		cpu_to_le16(offsetof(struct create_posix, Name));
+	buf->ccontext.NameLength = cpu_to_le16(16);
+
+	/* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
+	buf->Name[0] = 0x93;
+	buf->Name[1] = 0xAD;
+	buf->Name[2] = 0x25;
+	buf->Name[3] = 0x50;
+	buf->Name[4] = 0x9C;
+	buf->Name[5] = 0xB4;
+	buf->Name[6] = 0x11;
+	buf->Name[7] = 0xE7;
+	buf->Name[8] = 0xB4;
+	buf->Name[9] = 0x23;
+	buf->Name[10] = 0x83;
+	buf->Name[11] = 0xDE;
+	buf->Name[12] = 0x96;
+	buf->Name[13] = 0x8B;
+	buf->Name[14] = 0xCD;
+	buf->Name[15] = 0x7C;
+	buf->Mode = cpu_to_le32(mode);
+	cifs_dbg(FYI, "mode on posix create 0%o\n", mode);
+	return buf;
+}
+
+static int
+add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
+{
+	unsigned int num = *num_iovec;
+
+	iov[num].iov_base = create_posix_buf(mode);
+	if (mode == ACL_NO_MODE)
+		cifs_dbg(FYI, "%s: no mode\n", __func__);
+	if (iov[num].iov_base == NULL)
+		return -ENOMEM;
+	iov[num].iov_len = sizeof(struct create_posix);
+	*num_iovec = num + 1;
+	return 0;
+}
+
 static struct create_durable *
 create_durable_buf(void)
 {
@@ -2491,130 +2490,6 @@ create_reconnect_durable_buf(struct cifs_fid *fid)
 	return buf;
 }
 
-static void
-parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
-{
-	struct create_disk_id_rsp *pdisk_id = (struct create_disk_id_rsp *)cc;
-
-	cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
-		pdisk_id->DiskFileId, pdisk_id->VolumeId);
-	buf->IndexNumber = pdisk_id->DiskFileId;
-}
-
-static void
-parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
-		 struct create_posix_rsp *posix)
-{
-	int sid_len;
-	u8 *beg = (u8 *)cc + le16_to_cpu(cc->DataOffset);
-	u8 *end = beg + le32_to_cpu(cc->DataLength);
-	u8 *sid;
-
-	memset(posix, 0, sizeof(*posix));
-
-	posix->nlink = le32_to_cpu(*(__le32 *)(beg + 0));
-	posix->reparse_tag = le32_to_cpu(*(__le32 *)(beg + 4));
-	posix->mode = le32_to_cpu(*(__le32 *)(beg + 8));
-
-	sid = beg + 12;
-	sid_len = posix_info_sid_size(sid, end);
-	if (sid_len < 0) {
-		cifs_dbg(VFS, "bad owner sid in posix create response\n");
-		return;
-	}
-	memcpy(&posix->owner, sid, sid_len);
-
-	sid = sid + sid_len;
-	sid_len = posix_info_sid_size(sid, end);
-	if (sid_len < 0) {
-		cifs_dbg(VFS, "bad group sid in posix create response\n");
-		return;
-	}
-	memcpy(&posix->group, sid, sid_len);
-
-	cifs_dbg(FYI, "nlink=%d mode=%o reparse_tag=%x\n",
-		 posix->nlink, posix->mode, posix->reparse_tag);
-}
-
-int smb2_parse_contexts(struct TCP_Server_Info *server,
-			struct kvec *rsp_iov,
-			__u16 *epoch,
-			char *lease_key, __u8 *oplock,
-			struct smb2_file_all_info *buf,
-			struct create_posix_rsp *posix)
-{
-	struct smb2_create_rsp *rsp = rsp_iov->iov_base;
-	struct create_context *cc;
-	size_t rem, off, len;
-	size_t doff, dlen;
-	size_t noff, nlen;
-	char *name;
-	static const char smb3_create_tag_posix[] = {
-		0x93, 0xAD, 0x25, 0x50, 0x9C,
-		0xB4, 0x11, 0xE7, 0xB4, 0x23, 0x83,
-		0xDE, 0x96, 0x8B, 0xCD, 0x7C
-	};
-
-	*oplock = 0;
-
-	off = le32_to_cpu(rsp->CreateContextsOffset);
-	rem = le32_to_cpu(rsp->CreateContextsLength);
-	if (check_add_overflow(off, rem, &len) || len > rsp_iov->iov_len)
-		return -EINVAL;
-	cc = (struct create_context *)((u8 *)rsp + off);
-
-	/* Initialize inode number to 0 in case no valid data in qfid context */
-	if (buf)
-		buf->IndexNumber = 0;
-
-	while (rem >= sizeof(*cc)) {
-		doff = le16_to_cpu(cc->DataOffset);
-		dlen = le32_to_cpu(cc->DataLength);
-		if (check_add_overflow(doff, dlen, &len) || len > rem)
-			return -EINVAL;
-
-		noff = le16_to_cpu(cc->NameOffset);
-		nlen = le16_to_cpu(cc->NameLength);
-		if (noff + nlen > doff)
-			return -EINVAL;
-
-		name = (char *)cc + noff;
-		switch (nlen) {
-		case 4:
-			if (!strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
-				*oplock = server->ops->parse_lease_buf(cc, epoch,
-								       lease_key);
-			} else if (buf &&
-				   !strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4)) {
-				parse_query_id_ctxt(cc, buf);
-			}
-			break;
-		case 16:
-			if (posix && !memcmp(name, smb3_create_tag_posix, 16))
-				parse_posix_ctxt(cc, buf, posix);
-			break;
-		default:
-			cifs_dbg(FYI, "%s: unhandled context (nlen=%zu dlen=%zu)\n",
-				 __func__, nlen, dlen);
-			if (IS_ENABLED(CONFIG_CIFS_DEBUG2))
-				cifs_dump_mem("context data: ", cc, dlen);
-			break;
-		}
-
-		off = le32_to_cpu(cc->Next);
-		if (!off)
-			break;
-		if (check_sub_overflow(rem, off, &rem))
-			return -EINVAL;
-		cc = (struct create_context *)((u8 *)cc + off);
-	}
-
-	if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
-		*oplock = rsp->OplockLevel;
-
-	return 0;
-}
-
 static int
 add_lease_context(struct TCP_Server_Info *server,
 		  struct smb2_create_req *req,
@@ -3383,6 +3258,130 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
 	return 0;
 }
 
+static void
+parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
+{
+	struct create_disk_id_rsp *pdisk_id = (struct create_disk_id_rsp *)cc;
+
+	cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
+		pdisk_id->DiskFileId, pdisk_id->VolumeId);
+	buf->IndexNumber = pdisk_id->DiskFileId;
+}
+
+static void
+parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
+		 struct create_posix_rsp *posix)
+{
+	int sid_len;
+	u8 *beg = (u8 *)cc + le16_to_cpu(cc->DataOffset);
+	u8 *end = beg + le32_to_cpu(cc->DataLength);
+	u8 *sid;
+
+	memset(posix, 0, sizeof(*posix));
+
+	posix->nlink = le32_to_cpu(*(__le32 *)(beg + 0));
+	posix->reparse_tag = le32_to_cpu(*(__le32 *)(beg + 4));
+	posix->mode = le32_to_cpu(*(__le32 *)(beg + 8));
+
+	sid = beg + 12;
+	sid_len = posix_info_sid_size(sid, end);
+	if (sid_len < 0) {
+		cifs_dbg(VFS, "bad owner sid in posix create response\n");
+		return;
+	}
+	memcpy(&posix->owner, sid, sid_len);
+
+	sid = sid + sid_len;
+	sid_len = posix_info_sid_size(sid, end);
+	if (sid_len < 0) {
+		cifs_dbg(VFS, "bad group sid in posix create response\n");
+		return;
+	}
+	memcpy(&posix->group, sid, sid_len);
+
+	cifs_dbg(FYI, "nlink=%d mode=%o reparse_tag=%x\n",
+		 posix->nlink, posix->mode, posix->reparse_tag);
+}
+
+int smb2_parse_contexts(struct TCP_Server_Info *server,
+			struct kvec *rsp_iov,
+			__u16 *epoch,
+			char *lease_key, __u8 *oplock,
+			struct smb2_file_all_info *buf,
+			struct create_posix_rsp *posix)
+{
+	struct smb2_create_rsp *rsp = rsp_iov->iov_base;
+	struct create_context *cc;
+	size_t rem, off, len;
+	size_t doff, dlen;
+	size_t noff, nlen;
+	char *name;
+	static const char smb3_create_tag_posix[] = {
+		0x93, 0xAD, 0x25, 0x50, 0x9C,
+		0xB4, 0x11, 0xE7, 0xB4, 0x23, 0x83,
+		0xDE, 0x96, 0x8B, 0xCD, 0x7C
+	};
+
+	*oplock = 0;
+
+	off = le32_to_cpu(rsp->CreateContextsOffset);
+	rem = le32_to_cpu(rsp->CreateContextsLength);
+	if (check_add_overflow(off, rem, &len) || len > rsp_iov->iov_len)
+		return -EINVAL;
+	cc = (struct create_context *)((u8 *)rsp + off);
+
+	/* Initialize inode number to 0 in case no valid data in qfid context */
+	if (buf)
+		buf->IndexNumber = 0;
+
+	while (rem >= sizeof(*cc)) {
+		doff = le16_to_cpu(cc->DataOffset);
+		dlen = le32_to_cpu(cc->DataLength);
+		if (check_add_overflow(doff, dlen, &len) || len > rem)
+			return -EINVAL;
+
+		noff = le16_to_cpu(cc->NameOffset);
+		nlen = le16_to_cpu(cc->NameLength);
+		if (noff + nlen > doff)
+			return -EINVAL;
+
+		name = (char *)cc + noff;
+		switch (nlen) {
+		case 4:
+			if (!strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
+				*oplock = server->ops->parse_lease_buf(cc, epoch,
+								       lease_key);
+			} else if (buf &&
+				   !strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4)) {
+				parse_query_id_ctxt(cc, buf);
+			}
+			break;
+		case 16:
+			if (posix && !memcmp(name, smb3_create_tag_posix, 16))
+				parse_posix_ctxt(cc, buf, posix);
+			break;
+		default:
+			cifs_dbg(FYI, "%s: unhandled context (nlen=%zu dlen=%zu)\n",
+				 __func__, nlen, dlen);
+			if (IS_ENABLED(CONFIG_CIFS_DEBUG2))
+				cifs_dump_mem("context data: ", cc, dlen);
+			break;
+		}
+
+		off = le32_to_cpu(cc->Next);
+		if (!off)
+			break;
+		if (check_sub_overflow(rem, off, &rem))
+			return -EINVAL;
+		cc = (struct create_context *)((u8 *)cc + off);
+	}
+
+	if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
+		*oplock = rsp->OplockLevel;
+
+	return 0;
+}
+
 /* rq_iov[0] is the request and is released by cifs_small_buf_release().
  * All other vectors are freed by kfree().
  */


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ