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
next prev 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).