From: nspmangalore@gmail.com
To: linux-cifs@vger.kernel.org, smfrench@gmail.com, pc@manguebit.com,
bharathsm@microsoft.com, dhowells@redhat.com
Cc: Shyam Prasad N <sprasad@microsoft.com>
Subject: [PATCH] cifs: implementation id context as negotiate context
Date: Wed, 4 Mar 2026 17:57:15 +0530 [thread overview]
Message-ID: <20260304122910.1612435-1-sprasad@microsoft.com> (raw)
From: Shyam Prasad N <sprasad@microsoft.com>
MS-SMB2 does not allow any fields for the client to communicate
the client version details to the server. This change is a
proof-of-concept to add client details in a new negotiate context.
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
---
fs/smb/client/smb2pdu.c | 78 +++++++++++++++++++++++++++++++++++++++++
fs/smb/common/smb2pdu.h | 32 +++++++++++++++++
2 files changed, 110 insertions(+)
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index ef655acf673df..9c89f6b4a6709 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -24,6 +24,7 @@
#include <linux/pagemap.h>
#include <linux/xattr.h>
#include <linux/netfs.h>
+#include <linux/utsname.h>
#include <trace/events/netfs.h>
#include "cifsglob.h"
#include "cifsproto.h"
@@ -45,6 +46,7 @@
#include "cached_dir.h"
#include "compress.h"
#include "fs_context.h"
+#include "cifsfs.h"
/*
* The following table defines the expected "StructureSize" of SMB2 requests
@@ -724,6 +726,75 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
pneg_ctxt->Name[15] = 0x7C;
}
+static unsigned int
+build_implementation_id_ctxt(struct smb2_implementation_id_context *pneg_ctxt)
+{
+ struct nls_table *cp = load_nls_default();
+ struct new_utsname *uts = utsname();
+ const char *impl_domain = "kernel.org";
+ const char *impl_name = "fs/smb/client";
+ const char *os_name = "Linux";
+ unsigned int data_len = 0;
+ __u8 *data_ptr;
+ int len;
+
+ pneg_ctxt->ContextType = SMB2_IMPLEMENTATION_ID_CONTEXT_ID;
+ data_ptr = pneg_ctxt->Data;
+
+ /* ImplDomain */
+ len = cifs_strtoUTF16((__le16 *)data_ptr, impl_domain,
+ SMB2_IMPL_ID_MAX_DOMAIN_LEN, cp);
+ pneg_ctxt->ImplDomainLength = cpu_to_le16(len * 2);
+ data_ptr += len * 2;
+ data_len += len * 2;
+
+ /* ImplName */
+ len = cifs_strtoUTF16((__le16 *)data_ptr, impl_name,
+ SMB2_IMPL_ID_MAX_NAME_LEN, cp);
+ pneg_ctxt->ImplNameLength = cpu_to_le16(len * 2);
+ data_ptr += len * 2;
+ data_len += len * 2;
+
+ /* ImplVersion - CIFS_VERSION from cifsfs.h */
+ len = cifs_strtoUTF16((__le16 *)data_ptr, CIFS_VERSION,
+ SMB2_IMPL_ID_MAX_VERSION_LEN, cp);
+ pneg_ctxt->ImplVersionLength = cpu_to_le16(len * 2);
+ data_ptr += len * 2;
+ data_len += len * 2;
+
+ /* HostName - from utsname()->nodename */
+ len = cifs_strtoUTF16((__le16 *)data_ptr, uts->nodename,
+ SMB2_IMPL_ID_MAX_HOSTNAME_LEN, cp);
+ pneg_ctxt->HostNameLength = cpu_to_le16(len * 2);
+ data_ptr += len * 2;
+ data_len += len * 2;
+
+ /* OSName */
+ len = cifs_strtoUTF16((__le16 *)data_ptr, os_name,
+ SMB2_IMPL_ID_MAX_OS_NAME_LEN, cp);
+ pneg_ctxt->OSNameLength = cpu_to_le16(len * 2);
+ data_ptr += len * 2;
+ data_len += len * 2;
+
+ /* OSVersion - from utsname()->release */
+ len = cifs_strtoUTF16((__le16 *)data_ptr, uts->release,
+ SMB2_IMPL_ID_MAX_OS_VERSION_LEN, cp);
+ pneg_ctxt->OSVersionLength = cpu_to_le16(len * 2);
+ data_ptr += len * 2;
+ data_len += len * 2;
+
+ /* Arch - from utsname()->machine */
+ len = cifs_strtoUTF16((__le16 *)data_ptr, uts->machine,
+ SMB2_IMPL_ID_MAX_ARCH_LEN, cp);
+ pneg_ctxt->ArchLength = cpu_to_le16(len * 2);
+ data_len += len * 2;
+
+ pneg_ctxt->Reserved2 = 0;
+ pneg_ctxt->DataLength = cpu_to_le16(data_len + 14); /* 14 = 7 length fields * 2 bytes */
+ /* Context size is DataLength + minimal smb2_neg_context, aligned to 8 */
+ return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
+}
+
static void
assemble_neg_contexts(struct smb2_negotiate_req *req,
struct TCP_Server_Info *server, unsigned int *total_len)
@@ -797,6 +868,13 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
neg_context_count++;
}
+ /* Add implementation ID context */
+ ctxt_len = build_implementation_id_ctxt((struct smb2_implementation_id_context *)
+ pneg_ctxt);
+ *total_len += ctxt_len;
+ pneg_ctxt += ctxt_len;
+ neg_context_count++;
+
/* check for and add transport_capabilities and signing capabilities */
req->NegotiateContextCount = cpu_to_le16(neg_context_count);
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index e482c86ceb00d..1ad7b57ce2952 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -457,6 +457,7 @@ struct smb2_tree_disconnect_rsp {
#define SMB2_TRANSPORT_CAPABILITIES cpu_to_le16(6)
#define SMB2_RDMA_TRANSFORM_CAPABILITIES cpu_to_le16(7)
#define SMB2_SIGNING_CAPABILITIES cpu_to_le16(8)
+#define SMB2_IMPLEMENTATION_ID_CONTEXT_ID cpu_to_le16(0xF100)
#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100)
struct smb2_neg_context {
@@ -596,6 +597,37 @@ struct smb2_signing_capabilities {
/* Followed by padding to 8 byte boundary (required by some servers) */
} __packed;
+/*
+ * For implementation ID context see MS-SMB2 2.2.3.1.8
+ * Maximum string lengths per specification
+ */
+#define SMB2_IMPL_ID_MAX_DOMAIN_LEN 128
+#define SMB2_IMPL_ID_MAX_NAME_LEN 260
+#define SMB2_IMPL_ID_MAX_VERSION_LEN 260
+#define SMB2_IMPL_ID_MAX_HOSTNAME_LEN 64
+#define SMB2_IMPL_ID_MAX_OS_NAME_LEN 64
+#define SMB2_IMPL_ID_MAX_OS_VERSION_LEN 64
+#define SMB2_IMPL_ID_MAX_ARCH_LEN 64
+
+struct smb2_implementation_id_context {
+ __le16 ContextType; /* 9 */
+ __le16 DataLength;
+ __le32 Reserved;
+ __le16 ImplDomainLength;
+ __le16 ImplNameLength;
+ __le16 ImplVersionLength;
+ __le16 HostNameLength;
+ __le16 OSNameLength;
+ __le16 OSVersionLength;
+ __le16 ArchLength;
+ __le16 Reserved2;
+ /* Followed by variable length UTF-16 strings:
+ * ImplDomain, ImplName, ImplVersion, HostName,
+ * OSName, OSVersion, Arch
+ */
+ __u8 Data[];
+} __packed;
+
#define POSIX_CTXT_DATA_LEN 16
struct smb2_posix_neg_context {
__le16 ContextType; /* 0x100 */
--
2.43.0
next reply other threads:[~2026-03-04 12:29 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-04 12:27 nspmangalore [this message]
2026-03-04 12:34 ` [PATCH] cifs: implementation id context as negotiate context Shyam Prasad N
2026-03-06 22:45 ` Henrique Carvalho
2026-03-06 23:04 ` Steve French
2026-03-06 23:19 ` Paulo Alcantara
2026-03-06 23:23 ` Steve French
2026-03-09 16:34 ` Shyam Prasad N
2026-03-06 23:30 ` Henrique Carvalho
2026-03-09 16:19 ` Ralph Boehme
2026-03-09 16:37 ` Shyam Prasad N
2026-03-09 17:35 ` Ralph Boehme
2026-03-11 23:50 ` Shyam Prasad N
2026-03-09 17:59 ` Enzo Matsumiya
2026-03-11 23:52 ` Shyam Prasad N
2026-03-12 0:00 ` Steve French
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=20260304122910.1612435-1-sprasad@microsoft.com \
--to=nspmangalore@gmail.com \
--cc=bharathsm@microsoft.com \
--cc=dhowells@redhat.com \
--cc=linux-cifs@vger.kernel.org \
--cc=pc@manguebit.com \
--cc=smfrench@gmail.com \
--cc=sprasad@microsoft.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