All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] smb: client: reject a tree connect response whose byte count is too small
@ 2026-07-28 18:06 ` Bryam Vargas
  0 siblings, 0 replies; 3+ messages in thread
From: Bryam Vargas via B4 Relay @ 2026-07-28 18:06 UTC (permalink / raw)
  To: Steve French, Paulo Alcantara
  Cc: Shyam Prasad N, samba-technical, Ronnie Sahlberg, Jeff Layton,
	linux-cifs, linux-kernel, Tom Talpey, Bharath SM, David Howells

From: Bryam Vargas <hexlabsecurity@proton.me>

CIFSTCon() bounds its strnlen() over the byte area with the server's
ByteCount minus two, which for ByteCount 0 or 1 goes negative as an int
and converts to a huge size_t.  The later subtraction then wraps __u16
bytes_left, and that is what bounds cifs_strndup_from_utf16().

pByteArea() scales with the response's WordCount, also server-chosen, so
the walk can start past everything the request itself wrote, of which
cifs_buf_get() clears only the first 67 bytes.  KMSAN reports the read of
uninitialised heap, and the bytes reach userspace through
tcon->nativeFileSystem in /proc/fs/cifs/DebugData.

Reject a byte area too small for what the parser consumes.  A response
carrying a service string has at least two bytes there, so nothing valid
is rejected, and both subtractions are then safe.

Fixes: cc20c031bb06 ("cifs: convert CIFSTCon to use new unicode helper functions")
Cc: stable@kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
---
Found with KMSAN.  KASAN cannot see this one: the read never leaves the allocation.

The server picks both ends of the walk.  pByteArea() is buf + 33 + 2*WordCount + 2 and
CIFSTCon() does not check WordCount, so WordCount 128 puts bcc_ptr at 291 -- past the 67 bytes
cifs_buf_get() clears, past the 256 header_assemble() clears, and past everything the request
itself wrote.  checkSMB() is satisfied, since clc_len = 33 + 2*128 + 2 + 0 = 291 and the
response is exactly 291 bytes.  ByteCount 0 then removes the bound.

Reproducer.  A fake SMB1 server that answers negprot, completes SESSION_SETUP_ANDX, and replies
to TREE_CONNECT_ANDX with WordCount 128 and ByteCount 0.

A/B on v7.2-rc1 with KMSAN, the module rebuilt between arms and the previous session torn down
each time:

  wct 3,   BCC 8, unpatched:   0 reports
  wct 128, BCC 0, patched:     0 reports
  wct 128, BCC 0, unpatched:   110 reports, 28 of them in cifs_utf16_bytes

    BUG: KMSAN: uninit-value in cifs_utf16_bytes+0x37e/0x400 [cifs]
     cifs_utf16_bytes+0x37e/0x400 [cifs]
     cifs_strndup_from_utf16+0x5c/0x210 [cifs]
     CIFSTCon+0x1102/0x1510 [cifs]
     cifs_setup_ipc+0x3b9/0xcf0 [cifs]
     cifs_get_smb_ses+0x16e7/0x2cf0 [cifs]
     cifs_mount_get_session+0x2b2/0x730 [cifs]
     dfs_mount_share+0x43c/0x3510 [cifs]
     cifs_mount+0xcc/0x1140 [cifs]
     __se_sys_fsconfig+0x6e5/0xb10

    Uninit was created at:
     kmem_cache_alloc_noprof+0x556/0xf40
     mempool_alloc_noprof+0x104/0x240
     cifs_buf_get+0x45/0xc0 [cifs]
     CIFSTCon+0x77/0x1510 [cifs]
     cifs_setup_ipc+0x3b9/0xcf0 [cifs]

The uninitialised buffer is allocated by the same CIFSTCon() call that reads it, and the path is
cifs_setup_ipc(), so this fires on the IPC$ tree connect every SMB1 mount performs.  A separate
run caught it through smb2_reconnect_server() as well, i.e. with nobody at the keyboard.

A KMSAN positive control ran first on the same kernel and the same out-of-tree build -- a module
branching on an OPTIMIZER_HIDE_VAR'd uninitialised local -- and reported.  Without that the two
zeros above wouldn't mean anything, since clang folds a plain undef to a defined value.

DebugData is created with proc_create_single("DebugData", 0, ...), and mode 0 is promoted to
S_IRUGO; ls -l confirms -r--r--r--.  open_files, created on the next line, asks for 0400.

690c522fa5a6 ("cifs: use get/put_unaligned functions to access ByteCount") is what made
bytes_left a __u16, so the second subtraction wraps rather than going negative.  The strnlen()
underflow predates it.

I did not add a WordCount check.  checkSMB() rejects a frame shorter than its calculated size,
so once bytes_left is honest the byte area is always inside what was received.

The field this fills is only informational, and failing the whole tree connect over it is a
choice -- but a response with fewer than two bytes of byte area carries no service string, so
there is nothing left to parse.  Happy to make it skip the field and keep the mount if you'd
rather.
---
 fs/smb/client/cifssmb.c | 6 ++++++
 fs/smb/client/trace.h   | 1 +
 2 files changed, 7 insertions(+)

diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 40162d5554ea..bb835fdae296 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -615,6 +615,11 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
 		tcon->tid = smb_buffer_response->Tid;
 		bcc_ptr = pByteArea(smb_buffer_response);
 		bytes_left = get_bcc(smb_buffer_response);
+		if (bytes_left < 2) {
+			rc = smb_EIO2(smb_eio_trace_tcon_bcc_too_small,
+				      bytes_left, 2);
+			goto out;
+		}
 		length = strnlen(bcc_ptr, bytes_left - 2);
 		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
 			is_unicode = true;
@@ -670,6 +675,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
 			reset_cifs_unix_caps(xid, tcon, NULL, NULL);
 		}
 	}
+out:
 	cifs_buf_release(smb_buffer);
 	return rc;
 }
diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
index 5b21ad3c15fb..94de11d1c490 100644
--- a/fs/smb/client/trace.h
+++ b/fs/smb/client/trace.h
@@ -133,6 +133,7 @@
 	EM(smb_eio_trace_sym_slash,			"sym_slash") \
 	EM(smb_eio_trace_sym_target_len,		"sym_target_len") \
 	EM(smb_eio_trace_symlink_file_size,		"symlink_file_size") \
+	EM(smb_eio_trace_tcon_bcc_too_small,		"tcon_bcc_too_small") \
 	EM(smb_eio_trace_tdis_in_reconnect,		"tdis_in_reconnect") \
 	EM(smb_eio_trace_tx_chained_async,		"tx_chained_async") \
 	EM(smb_eio_trace_tx_compress_failed,		"tx_compress_failed") \

---
base-commit: 4235cb24ec1e8e96843f3671ba4da2a6ccca2c7b
change-id: 20260728-b4-disp-6b8e68d4-fa25e109c92e

Best regards,
--  
Bryam Vargas <hexlabsecurity@proton.me>



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH] smb: client: reject a tree connect response whose byte count is too small
@ 2026-07-28 18:06 ` Bryam Vargas
  0 siblings, 0 replies; 3+ messages in thread
From: Bryam Vargas @ 2026-07-28 18:06 UTC (permalink / raw)
  To: Steve French, Paulo Alcantara
  Cc: Shyam Prasad N, samba-technical, Ronnie Sahlberg, Jeff Layton,
	linux-cifs, linux-kernel, Tom Talpey, Bharath SM, David Howells

CIFSTCon() bounds its strnlen() over the byte area with the server's
ByteCount minus two, which for ByteCount 0 or 1 goes negative as an int
and converts to a huge size_t.  The later subtraction then wraps __u16
bytes_left, and that is what bounds cifs_strndup_from_utf16().

pByteArea() scales with the response's WordCount, also server-chosen, so
the walk can start past everything the request itself wrote, of which
cifs_buf_get() clears only the first 67 bytes.  KMSAN reports the read of
uninitialised heap, and the bytes reach userspace through
tcon->nativeFileSystem in /proc/fs/cifs/DebugData.

Reject a byte area too small for what the parser consumes.  A response
carrying a service string has at least two bytes there, so nothing valid
is rejected, and both subtractions are then safe.

Fixes: cc20c031bb06 ("cifs: convert CIFSTCon to use new unicode helper functions")
Cc: stable@kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
---
Found with KMSAN.  KASAN cannot see this one: the read never leaves the allocation.

The server picks both ends of the walk.  pByteArea() is buf + 33 + 2*WordCount + 2 and
CIFSTCon() does not check WordCount, so WordCount 128 puts bcc_ptr at 291 -- past the 67 bytes
cifs_buf_get() clears, past the 256 header_assemble() clears, and past everything the request
itself wrote.  checkSMB() is satisfied, since clc_len = 33 + 2*128 + 2 + 0 = 291 and the
response is exactly 291 bytes.  ByteCount 0 then removes the bound.

Reproducer.  A fake SMB1 server that answers negprot, completes SESSION_SETUP_ANDX, and replies
to TREE_CONNECT_ANDX with WordCount 128 and ByteCount 0.

A/B on v7.2-rc1 with KMSAN, the module rebuilt between arms and the previous session torn down
each time:

  wct 3,   BCC 8, unpatched:   0 reports
  wct 128, BCC 0, patched:     0 reports
  wct 128, BCC 0, unpatched:   110 reports, 28 of them in cifs_utf16_bytes

    BUG: KMSAN: uninit-value in cifs_utf16_bytes+0x37e/0x400 [cifs]
     cifs_utf16_bytes+0x37e/0x400 [cifs]
     cifs_strndup_from_utf16+0x5c/0x210 [cifs]
     CIFSTCon+0x1102/0x1510 [cifs]
     cifs_setup_ipc+0x3b9/0xcf0 [cifs]
     cifs_get_smb_ses+0x16e7/0x2cf0 [cifs]
     cifs_mount_get_session+0x2b2/0x730 [cifs]
     dfs_mount_share+0x43c/0x3510 [cifs]
     cifs_mount+0xcc/0x1140 [cifs]
     __se_sys_fsconfig+0x6e5/0xb10

    Uninit was created at:
     kmem_cache_alloc_noprof+0x556/0xf40
     mempool_alloc_noprof+0x104/0x240
     cifs_buf_get+0x45/0xc0 [cifs]
     CIFSTCon+0x77/0x1510 [cifs]
     cifs_setup_ipc+0x3b9/0xcf0 [cifs]

The uninitialised buffer is allocated by the same CIFSTCon() call that reads it, and the path is
cifs_setup_ipc(), so this fires on the IPC$ tree connect every SMB1 mount performs.  A separate
run caught it through smb2_reconnect_server() as well, i.e. with nobody at the keyboard.

A KMSAN positive control ran first on the same kernel and the same out-of-tree build -- a module
branching on an OPTIMIZER_HIDE_VAR'd uninitialised local -- and reported.  Without that the two
zeros above wouldn't mean anything, since clang folds a plain undef to a defined value.

DebugData is created with proc_create_single("DebugData", 0, ...), and mode 0 is promoted to
S_IRUGO; ls -l confirms -r--r--r--.  open_files, created on the next line, asks for 0400.

690c522fa5a6 ("cifs: use get/put_unaligned functions to access ByteCount") is what made
bytes_left a __u16, so the second subtraction wraps rather than going negative.  The strnlen()
underflow predates it.

I did not add a WordCount check.  checkSMB() rejects a frame shorter than its calculated size,
so once bytes_left is honest the byte area is always inside what was received.

The field this fills is only informational, and failing the whole tree connect over it is a
choice -- but a response with fewer than two bytes of byte area carries no service string, so
there is nothing left to parse.  Happy to make it skip the field and keep the mount if you'd
rather.
---
 fs/smb/client/cifssmb.c | 6 ++++++
 fs/smb/client/trace.h   | 1 +
 2 files changed, 7 insertions(+)

diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 40162d5554ea..bb835fdae296 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -615,6 +615,11 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
 		tcon->tid = smb_buffer_response->Tid;
 		bcc_ptr = pByteArea(smb_buffer_response);
 		bytes_left = get_bcc(smb_buffer_response);
+		if (bytes_left < 2) {
+			rc = smb_EIO2(smb_eio_trace_tcon_bcc_too_small,
+				      bytes_left, 2);
+			goto out;
+		}
 		length = strnlen(bcc_ptr, bytes_left - 2);
 		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
 			is_unicode = true;
@@ -670,6 +675,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
 			reset_cifs_unix_caps(xid, tcon, NULL, NULL);
 		}
 	}
+out:
 	cifs_buf_release(smb_buffer);
 	return rc;
 }
diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
index 5b21ad3c15fb..94de11d1c490 100644
--- a/fs/smb/client/trace.h
+++ b/fs/smb/client/trace.h
@@ -133,6 +133,7 @@
 	EM(smb_eio_trace_sym_slash,			"sym_slash") \
 	EM(smb_eio_trace_sym_target_len,		"sym_target_len") \
 	EM(smb_eio_trace_symlink_file_size,		"symlink_file_size") \
+	EM(smb_eio_trace_tcon_bcc_too_small,		"tcon_bcc_too_small") \
 	EM(smb_eio_trace_tdis_in_reconnect,		"tdis_in_reconnect") \
 	EM(smb_eio_trace_tx_chained_async,		"tx_chained_async") \
 	EM(smb_eio_trace_tx_compress_failed,		"tx_compress_failed") \

---
base-commit: 4235cb24ec1e8e96843f3671ba4da2a6ccca2c7b
change-id: 20260728-b4-disp-6b8e68d4-fa25e109c92e

Best regards,
--  
Bryam Vargas <hexlabsecurity@proton.me>


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] smb: client: reject a tree connect response whose byte count is too small
  2026-07-28 18:06 ` Bryam Vargas
  (?)
@ 2026-07-29  1:42 ` kernel test robot
  -1 siblings, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-07-29  1:42 UTC (permalink / raw)
  To: Bryam Vargas via B4 Relay, Steve French, Paulo Alcantara
  Cc: llvm, oe-kbuild-all, Shyam Prasad N, samba-technical,
	Ronnie Sahlberg, Jeff Layton, linux-cifs, linux-kernel,
	Tom Talpey, Bharath SM, David Howells

Hi Bryam,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 4235cb24ec1e8e96843f3671ba4da2a6ccca2c7b]

url:    https://github.com/intel-lab-lkp/linux/commits/Bryam-Vargas-via-B4-Relay/smb-client-reject-a-tree-connect-response-whose-byte-count-is-too-small/20260729-024634
base:   4235cb24ec1e8e96843f3671ba4da2a6ccca2c7b
patch link:    https://lore.kernel.org/r/20260728-b4-disp-6b8e68d4-v1-1-e69277237297%40proton.me
patch subject: [PATCH] smb: client: reject a tree connect response whose byte count is too small
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260729/202607290953.sMPYxQPT-lkp@intel.com/config)
compiler: clang version 22.1.3 (https://github.com/llvm/llvm-project e9846648fd6183ee6d8cbdb4502213fcf902a211)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260729/202607290953.sMPYxQPT-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202607290953.sMPYxQPT-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> fs/smb/client/cifssmb.c:1791:19: warning: implicit conversion from 'int' to 'enum smb_eio_trace' changes value from 128 to -128 [-Wconstant-conversion]
    1791 |                         return smb_EIO(smb_eio_trace_write_too_far);
         |                                ~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/smb/client/cifssmb.c:1982:17: warning: implicit conversion from 'int' to 'enum smb_eio_trace' changes value from 128 to -128 [-Wconstant-conversion]
    1982 |                         rc = smb_EIO(smb_eio_trace_write_too_far);
         |                              ~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/smb/client/cifssmb.c:2074:19: warning: implicit conversion from 'int' to 'enum smb_eio_trace' changes value from 128 to -128 [-Wconstant-conversion]
    2074 |                         return smb_EIO(smb_eio_trace_write_too_far);
         |                                ~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   3 warnings generated.


vim +1791 fs/smb/client/cifssmb.c

^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1761  
ec637e3ffb6b97 fs/cifs/cifssmb.c       Steve French     2005-12-12  1762  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1763  int
6d5786a34d98bf fs/cifs/cifssmb.c       Pavel Shilovsky  2012-06-20  1764  CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
dbbab32574c384 fs/cifs/cifssmb.c       Al Viro          2016-09-05  1765  	     unsigned int *nbytes, const char *buf)
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1766  {
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1767  	int rc = -EACCES;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1768  	WRITE_REQ *pSMB = NULL;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1769  	WRITE_RSP *pSMBr = NULL;
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1770  	int bytes_returned, wct;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1771  	__u32 bytes_sent;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1772  	__u16 byte_count;
fa2989f4473413 fs/cifs/cifssmb.c       Pavel Shilovsky  2011-05-26  1773  	__u32 pid = io_parms->pid;
fa2989f4473413 fs/cifs/cifssmb.c       Pavel Shilovsky  2011-05-26  1774  	__u16 netfid = io_parms->netfid;
fa2989f4473413 fs/cifs/cifssmb.c       Pavel Shilovsky  2011-05-26  1775  	__u64 offset = io_parms->offset;
96daf2b09178d8 fs/cifs/cifssmb.c       Steve French     2011-05-27  1776  	struct cifs_tcon *tcon = io_parms->tcon;
83bfbd0bb9025f fs/smb/client/cifssmb.c David Howells    2025-09-05  1777  	unsigned int count = io_parms->length, in_len;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1778  
a24e2d7d8f5123 fs/cifs/cifssmb.c       Steve French     2010-04-03  1779  	*nbytes = 0;
a24e2d7d8f5123 fs/cifs/cifssmb.c       Steve French     2010-04-03  1780  
f96637be081141 fs/cifs/cifssmb.c       Joe Perches      2013-05-04  1781  	/* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1782  	if (tcon->ses == NULL)
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1783  		return -ECONNABORTED;
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1784  
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1785  	if (tcon->ses->capabilities & CAP_LARGE_FILES)
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1786  		wct = 14;
4c3130efda1ef4 fs/cifs/cifssmb.c       Steve French     2008-12-09  1787  	else {
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1788  		wct = 12;
4c3130efda1ef4 fs/cifs/cifssmb.c       Steve French     2008-12-09  1789  		if ((offset >> 32) > 0) {
4c3130efda1ef4 fs/cifs/cifssmb.c       Steve French     2008-12-09  1790  			/* can not handle big offset for old srv */
f80ac7eda1cf52 fs/smb/client/cifssmb.c David Howells    2025-10-24 @1791  			return smb_EIO(smb_eio_trace_write_too_far);
4c3130efda1ef4 fs/cifs/cifssmb.c       Steve French     2008-12-09  1792  		}
4c3130efda1ef4 fs/cifs/cifssmb.c       Steve French     2008-12-09  1793  	}
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1794  
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1795  	rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1796  		      (void **) &pSMBr);
83bfbd0bb9025f fs/smb/client/cifssmb.c David Howells    2025-09-05  1797  	if (rc < 0)
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1798  		return rc;
83bfbd0bb9025f fs/smb/client/cifssmb.c David Howells    2025-09-05  1799  	in_len = rc;
fa2989f4473413 fs/cifs/cifssmb.c       Pavel Shilovsky  2011-05-26  1800  
fa2989f4473413 fs/cifs/cifssmb.c       Pavel Shilovsky  2011-05-26  1801  	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
fa2989f4473413 fs/cifs/cifssmb.c       Pavel Shilovsky  2011-05-26  1802  	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
fa2989f4473413 fs/cifs/cifssmb.c       Pavel Shilovsky  2011-05-26  1803  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1804  	/* tcon and ses pointer are checked in smb_init */
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1805  	if (tcon->ses->server == NULL)
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1806  		return -ECONNABORTED;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1807  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1808  	pSMB->AndXCommand = 0xFF;	/* none */
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1809  	pSMB->Fid = netfid;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1810  	pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1811  	if (wct == 14)
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1812  		pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1813  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1814  	pSMB->Reserved = 0xFFFFFFFF;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1815  	pSMB->WriteMode = 0;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1816  	pSMB->Remaining = 0;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1817  
50c2f753887270 fs/cifs/cifssmb.c       Steve French     2007-07-13  1818  	/* Can increase buffer size if buffer is big enough in some cases ie we
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1819  	can send more if LARGE_WRITE_X capability returned by the server and if
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1820  	our buffer is big enough or if we convert to iovecs on socket writes
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1821  	and eliminate the copy to the CIFS buffer */
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1822  	if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1823  		bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1824  	} else {
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1825  		bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1826  			 & ~0xFF;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1827  	}
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1828  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1829  	if (bytes_sent > count)
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1830  		bytes_sent = count;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1831  	pSMB->DataOffset =
83bfbd0bb9025f fs/smb/client/cifssmb.c David Howells    2025-09-05  1832  		cpu_to_le16(offsetof(struct smb_com_write_req, Data));
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1833  	if (buf)
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1834  		memcpy(pSMB->Data, buf, bytes_sent);
dbbab32574c384 fs/cifs/cifssmb.c       Al Viro          2016-09-05  1835  	else if (count != 0) {
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1836  		/* No buffer */
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1837  		cifs_buf_release(pSMB);
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1838  		return -EINVAL;
e30dcf3a1905b4 fs/cifs/cifssmb.c       Steve French     2005-09-20  1839  	} /* else setting file size with write of zero bytes */
e30dcf3a1905b4 fs/cifs/cifssmb.c       Steve French     2005-09-20  1840  	if (wct == 14)
e30dcf3a1905b4 fs/cifs/cifssmb.c       Steve French     2005-09-20  1841  		byte_count = bytes_sent + 1; /* pad */
ad7a2926b9e53c fs/cifs/cifssmb.c       Steve French     2008-02-07  1842  	else /* wct == 12 */
e30dcf3a1905b4 fs/cifs/cifssmb.c       Steve French     2005-09-20  1843  		byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
ad7a2926b9e53c fs/cifs/cifssmb.c       Steve French     2008-02-07  1844  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1845  	pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1846  	pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
83bfbd0bb9025f fs/smb/client/cifssmb.c David Howells    2025-09-05  1847  	in_len += byte_count;
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1848  
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1849  	if (wct == 14)
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1850  		pSMB->ByteCount = cpu_to_le16(byte_count);
50c2f753887270 fs/cifs/cifssmb.c       Steve French     2007-07-13  1851  	else { /* old style write has byte count 4 bytes earlier
50c2f753887270 fs/cifs/cifssmb.c       Steve French     2007-07-13  1852  		  so 4 bytes pad  */
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1853  		struct smb_com_writex_req *pSMBW =
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1854  			(struct smb_com_writex_req *)pSMB;
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1855  		pSMBW->ByteCount = cpu_to_le16(byte_count);
1c9551878c4629 fs/cifs/cifssmb.c       Steve French     2005-08-30  1856  	}
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1857  
83bfbd0bb9025f fs/smb/client/cifssmb.c David Howells    2025-09-05  1858  	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
dbbab32574c384 fs/cifs/cifssmb.c       Al Viro          2016-09-05  1859  			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
44c581866e2ae4 fs/cifs/cifssmb.c       Pavel Shilovsky  2012-05-28  1860  	cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1861  	if (rc) {
f96637be081141 fs/cifs/cifssmb.c       Joe Perches      2013-05-04  1862  		cifs_dbg(FYI, "Send error in write = %d\n", rc);
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1863  	} else {
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1864  		*nbytes = le16_to_cpu(pSMBr->CountHigh);
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1865  		*nbytes = (*nbytes) << 16;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1866  		*nbytes += le16_to_cpu(pSMBr->Count);
6513a81e9325d7 fs/cifs/cifssmb.c       Suresh Jayaraman 2010-03-31  1867  
6513a81e9325d7 fs/cifs/cifssmb.c       Suresh Jayaraman 2010-03-31  1868  		/*
6513a81e9325d7 fs/cifs/cifssmb.c       Suresh Jayaraman 2010-03-31  1869  		 * Mask off high 16 bits when bytes written as returned by the
6513a81e9325d7 fs/cifs/cifssmb.c       Suresh Jayaraman 2010-03-31  1870  		 * server is greater than bytes requested by the client. Some
6513a81e9325d7 fs/cifs/cifssmb.c       Suresh Jayaraman 2010-03-31  1871  		 * OS/2 servers are known to set incorrect CountHigh values.
6513a81e9325d7 fs/cifs/cifssmb.c       Suresh Jayaraman 2010-03-31  1872  		 */
6513a81e9325d7 fs/cifs/cifssmb.c       Suresh Jayaraman 2010-03-31  1873  		if (*nbytes > count)
6513a81e9325d7 fs/cifs/cifssmb.c       Suresh Jayaraman 2010-03-31  1874  			*nbytes &= 0xFFFF;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1875  	}
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1876  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1877  	cifs_buf_release(pSMB);
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1878  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1879  	/* Note: On -EAGAIN error only caller can retry on handle based calls
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1880  		since file handle passed in no longer valid */
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1881  
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1882  	return rc;
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1883  }
^1da177e4c3f41 fs/cifs/cifssmb.c       Linus Torvalds   2005-04-16  1884  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-29  1:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-28 18:06 [PATCH] smb: client: reject a tree connect response whose byte count is too small Bryam Vargas via B4 Relay
2026-07-28 18:06 ` Bryam Vargas
2026-07-29  1:42 ` kernel test robot

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.