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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.