Linux-CIFS Archive mirror
 help / color / mirror / Atom feed
From: Henrique Carvalho <henrique.carvalho@suse.com>
To: linux-cifs@vger.kernel.org
Cc: sfrench@samba.org, linkinjeon@kernel.org, metze@samba.org,
	pc@manguebit.com, ronniesahlberg@gmail.com,
	sprasad@microsoft.com, tom@talpey.com, bharathsm@microsoft.com,
	ematsumiya@suse.de,
	Henrique Carvalho <henrique.carvalho@suse.com>
Subject: [PATCH v2 02/11] smb: client: refactor negotiate context assembly
Date: Tue, 28 Apr 2026 12:55:40 -0300	[thread overview]
Message-ID: <20260428155542.226234-3-henrique.carvalho@suse.com> (raw)
In-Reply-To: <20260428155542.226234-1-henrique.carvalho@suse.com>

Introduce struct neg_ctx, smb2_neg_context_len() and add_context() to
handle alignment, pointer advancement, and counter increment in one
place, eliminating repetitive code.

Also fix missing ALIGN() for posix negotiate context.

Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
---
 fs/smb/client/smb2pdu.c | 106 +++++++++++++++++++++-------------------
 1 file changed, 56 insertions(+), 50 deletions(-)

diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index cddb1ae04e83..bac88a612d5d 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -618,7 +618,15 @@ static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon,
 
 /* For explanation of negotiate contexts see MS-SMB2 section 2.2.3.1 */
 
-static void
+static inline unsigned int
+smb2_neg_context_len(const void *p)
+{
+	const struct smb2_neg_context *ctx = p;
+
+	return sizeof(*ctx) + le16_to_cpu(ctx->DataLength);
+}
+
+static unsigned int
 build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt)
 {
 	pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
@@ -627,9 +635,10 @@ build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt)
 	pneg_ctxt->SaltLength = cpu_to_le16(SMB311_SALT_SIZE);
 	get_random_bytes(pneg_ctxt->Salt, SMB311_SALT_SIZE);
 	pneg_ctxt->HashAlgorithms = SMB2_PREAUTH_INTEGRITY_SHA512;
+	return smb2_neg_context_len(pneg_ctxt);
 }
 
-static void
+static unsigned int
 build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt)
 {
 	pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES;
@@ -640,13 +649,13 @@ build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt)
 	pneg_ctxt->CompressionAlgorithms[0] = SMB3_COMPRESS_LZ77;
 	pneg_ctxt->CompressionAlgorithms[1] = SMB3_COMPRESS_LZ77_HUFF;
 	pneg_ctxt->CompressionAlgorithms[2] = SMB3_COMPRESS_LZNT1;
+	return smb2_neg_context_len(pneg_ctxt);
 }
 
 static unsigned int
 build_signing_ctxt(struct smb2_signing_capabilities *pneg_ctxt)
 {
-	unsigned int ctxt_len = sizeof(struct smb2_signing_capabilities);
-	unsigned short num_algs = 1; /* number of signing algorithms sent */
+	const unsigned short num_algs = 1; /* number of signing algorithms sent */
 
 	pneg_ctxt->ContextType = SMB2_SIGNING_CAPABILITIES;
 	/*
@@ -658,13 +667,11 @@ build_signing_ctxt(struct smb2_signing_capabilities *pneg_ctxt)
 	pneg_ctxt->SigningAlgorithmCount = cpu_to_le16(num_algs);
 	pneg_ctxt->SigningAlgorithms[0] = cpu_to_le16(SIGNING_ALG_AES_CMAC);
 
-	ctxt_len += sizeof(__le16) * num_algs;
-	ctxt_len = ALIGN(ctxt_len, 8);
-	return ctxt_len;
+	return smb2_neg_context_len(pneg_ctxt);
 	/* TBD add SIGNING_ALG_AES_GMAC and/or SIGNING_ALG_HMAC_SHA256 */
 }
 
-static void
+static unsigned int
 build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
 {
 	pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
@@ -684,6 +691,7 @@ build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
 		pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
 		pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES128_CCM;
 	}
+	return smb2_neg_context_len(pneg_ctxt);
 }
 
 static unsigned int
@@ -695,11 +703,11 @@ build_netname_ctxt(struct smb2_netname_neg_context *pneg_ctxt, char *hostname)
 
 	/* copy up to max of first 100 bytes of server name to NetName field */
 	pneg_ctxt->DataLength = cpu_to_le16(2 * cifs_strtoUTF16(pneg_ctxt->NetName, hostname, 100, cp));
-	/* context size is DataLength + minimal smb2_neg_context */
-	return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
+
+	return smb2_neg_context_len(pneg_ctxt);
 }
 
-static void
+static unsigned int
 build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
 {
 	pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
@@ -721,15 +729,31 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
 	pneg_ctxt->Name[13] = 0x8B;
 	pneg_ctxt->Name[14] = 0xCD;
 	pneg_ctxt->Name[15] = 0x7C;
+	return smb2_neg_context_len(pneg_ctxt);
+}
+
+struct neg_ctx {
+	char *pos;
+	unsigned int len;
+	unsigned int cnt;
+};
+
+static inline void
+add_context(struct neg_ctx *nc, unsigned int ctx_len)
+{
+	unsigned int aligned_len = ALIGN(ctx_len, 8);
+
+	nc->pos += aligned_len;
+	nc->len += aligned_len;
+	nc->cnt++;
 }
 
 static void
 assemble_neg_contexts(struct smb2_negotiate_req *req,
 		      struct TCP_Server_Info *server, unsigned int *total_len)
 {
-	unsigned int ctxt_len, neg_context_count;
+	struct neg_ctx nc;
 	struct TCP_Server_Info *pserver;
-	char *pneg_ctxt;
 	char *hostname;
 
 	if (*total_len > 200) {
@@ -744,18 +768,15 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
 	 */
 	*total_len = ALIGN(*total_len, 8);
 
-	pneg_ctxt = (*total_len) + (char *)req;
 	req->NegotiateContextOffset = cpu_to_le32(*total_len);
 
-	build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
-	ctxt_len = ALIGN(sizeof(struct smb2_preauth_neg_context), 8);
-	*total_len += ctxt_len;
-	pneg_ctxt += ctxt_len;
+	nc.pos = (*total_len) + (char *)req;
+	nc.len = *total_len;
+	nc.cnt = 0;
+
+	add_context(&nc, build_preauth_ctxt((struct smb2_preauth_neg_context *)nc.pos));
 
-	build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt);
-	ctxt_len = ALIGN(sizeof(struct smb2_encryption_neg_context), 8);
-	*total_len += ctxt_len;
-	pneg_ctxt += ctxt_len;
+	add_context(&nc, build_encrypt_ctxt((struct smb2_encryption_neg_context *)nc.pos));
 
 	/*
 	 * secondary channels don't have the hostname field populated
@@ -764,41 +785,26 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
 	pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
 	cifs_server_lock(pserver);
 	hostname = pserver->hostname;
-	if (hostname && (hostname[0] != 0)) {
-		ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt,
-					      hostname);
-		*total_len += ctxt_len;
-		pneg_ctxt += ctxt_len;
-		neg_context_count = 3;
-	} else
-		neg_context_count = 2;
+	if (hostname && (hostname[0] != 0))
+		add_context(&nc,
+			    build_netname_ctxt((struct smb2_netname_neg_context *)nc.pos,
+					       hostname));
 	cifs_server_unlock(pserver);
 
-	build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
-	*total_len += sizeof(struct smb2_posix_neg_context);
-	pneg_ctxt += sizeof(struct smb2_posix_neg_context);
-	neg_context_count++;
+	add_context(&nc, build_posix_ctxt((struct smb2_posix_neg_context *)nc.pos));
 
-	if (server->compression.requested) {
-		build_compression_ctxt((struct smb2_compression_capabilities_context *)
-				pneg_ctxt);
-		ctxt_len = ALIGN(sizeof(struct smb2_compression_capabilities_context), 8);
-		*total_len += ctxt_len;
-		pneg_ctxt += ctxt_len;
-		neg_context_count++;
-	}
+	if (server->compression.requested)
+		add_context(&nc,
+			    build_compression_ctxt(
+				    (struct smb2_compression_capabilities_context *)nc.pos));
 
-	if (enable_negotiate_signing) {
-		ctxt_len = build_signing_ctxt((struct smb2_signing_capabilities *)
-				pneg_ctxt);
-		*total_len += ctxt_len;
-		pneg_ctxt += ctxt_len;
-		neg_context_count++;
-	}
+	if (enable_negotiate_signing)
+		add_context(&nc, build_signing_ctxt((struct smb2_signing_capabilities *)nc.pos));
 
 	/* check for and add transport_capabilities and signing capabilities */
-	req->NegotiateContextCount = cpu_to_le16(neg_context_count);
+	req->NegotiateContextCount = cpu_to_le16(nc.cnt);
 
+	*total_len = nc.len;
 }
 
 /* If invalid preauth context warn but use what we requested, SHA-512 */
-- 
2.53.0


  parent reply	other threads:[~2026-04-28 15:56 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-28 15:55 [PATCH v2 00/11] smb: implement SMB over QUIC Henrique Carvalho
2026-04-28 15:55 ` [PATCH v2 01/11] smb: common: add smb_tls struct shared by client and server Henrique Carvalho
2026-04-28 15:55 ` Henrique Carvalho [this message]
2026-04-28 15:55 ` [PATCH v2 03/11] smb: client: prepare connect path for QUIC transport Henrique Carvalho
2026-04-28 15:55 ` [PATCH v2 04/11] smb: client: add QUIC mount and transport setup Henrique Carvalho

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260428155542.226234-3-henrique.carvalho@suse.com \
    --to=henrique.carvalho@suse.com \
    --cc=bharathsm@microsoft.com \
    --cc=ematsumiya@suse.de \
    --cc=linkinjeon@kernel.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=metze@samba.org \
    --cc=pc@manguebit.com \
    --cc=ronniesahlberg@gmail.com \
    --cc=sfrench@samba.org \
    --cc=sprasad@microsoft.com \
    --cc=tom@talpey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).