linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] cifs: Fix validation of WSL-style special files
@ 2025-06-08 17:01 Pali Rohár
  2025-06-08 17:01 ` [PATCH 1/5] cifs: Remove duplicate fattr->cf_dtype assignment from wsl_to_fattr() function Pali Rohár
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Pali Rohár @ 2025-06-08 17:01 UTC (permalink / raw)
  To: Steve French, Paulo Alcantara; +Cc: linux-cifs, linux-kernel

This patch series fixes validation of WSL special files by Linux SMB
client, to be compatible with WSL subsystem.

Pali Rohár (5):
  cifs: Remove setting duplicate fattr->cf_dtype from wsl_to_fattr()
    function
  cifs: Fix validation of EAs for WSL reparse points
  cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size
  cifs: Query EA $LXMOD in cifs_query_path_info() for WSL reparse points
  cifs: Validate presence of EA $LXMOD for WSL reparse points

 fs/smb/client/reparse.c | 40 ++++++++++++++++++++------
 fs/smb/client/smb1ops.c | 62 +++++++++++++++++++++++++++++++++++++++--
 fs/smb/client/smb2pdu.h | 19 ++++++-------
 3 files changed, 101 insertions(+), 20 deletions(-)

-- 
2.20.1


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

* [PATCH 1/5] cifs: Remove duplicate fattr->cf_dtype assignment from wsl_to_fattr() function
  2025-06-08 17:01 [PATCH 0/5] cifs: Fix validation of WSL-style special files Pali Rohár
@ 2025-06-08 17:01 ` Pali Rohár
  2025-06-08 17:01 ` [PATCH 2/5] cifs: Fix validation of EAs for WSL reparse points Pali Rohár
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Pali Rohár @ 2025-06-08 17:01 UTC (permalink / raw)
  To: Steve French, Paulo Alcantara; +Cc: linux-cifs, linux-kernel

Commit 8bd25b61c5a5 ("smb: client: set correct d_type for reparse DFS/DFSR
and mount point") deduplicated assignment of fattr->cf_dtype member from
all places to end of the function cifs_reparse_point_to_fattr(). The only
one missing place which was not deduplicated is wsl_to_fattr(). Fix it.

Fixes: 8bd25b61c5a5 ("smb: client: set correct d_type for reparse DFS/DFSR and mount point")
Signed-off-by: Pali Rohár <pali@kernel.org>
---
 fs/smb/client/reparse.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
index d1d25f5f72ca..5351d3d9d538 100644
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -1176,7 +1176,6 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
 	if (!have_xattr_dev && (tag == IO_REPARSE_TAG_LX_CHR || tag == IO_REPARSE_TAG_LX_BLK))
 		return false;
 
-	fattr->cf_dtype = S_DT(fattr->cf_mode);
 	return true;
 }
 
-- 
2.20.1


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

* [PATCH 2/5] cifs: Fix validation of EAs for WSL reparse points
  2025-06-08 17:01 [PATCH 0/5] cifs: Fix validation of WSL-style special files Pali Rohár
  2025-06-08 17:01 ` [PATCH 1/5] cifs: Remove duplicate fattr->cf_dtype assignment from wsl_to_fattr() function Pali Rohár
@ 2025-06-08 17:01 ` Pali Rohár
  2025-06-08 17:01 ` [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size Pali Rohár
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Pali Rohár @ 2025-06-08 17:01 UTC (permalink / raw)
  To: Steve French, Paulo Alcantara; +Cc: linux-cifs, linux-kernel

When wsl_to_fattr() is called from readdir() then we should skip validation
of WSL EAs because readdir FIND_FIRST/NEXT results do not provide EA values
at all. For readdir() reply in this case return DT_UNKNOWN type instead of
DT_REG (which is the result of failed WSL EAs validation).

When validation is skipped and some required EAs are missing then returns
true from wsl_to_fattr() function but do not set fattr->cf_mode. This makes
readdir() to return DT_UNKNOWN type in the same way as it is doing NFS
reparse point function.

This change fixes readdir() result that for some WSL reparse points returns
DT_REG due to missing EAs. After this change it returns DT_UNKNOWN, which
is better than returning wrong type.

Fixes: ef201e8759d2 ("cifs: Validate EAs for WSL reparse points")
Signed-off-by: Pali Rohár <pali@kernel.org>
---
 fs/smb/client/reparse.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
index 5351d3d9d538..8d989e436517 100644
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -1117,27 +1117,39 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
 			 u32 tag, struct cifs_fattr *fattr)
 {
 	struct smb2_file_full_ea_info *ea;
+	bool ignore_missing_eas = false;
 	bool have_xattr_dev = false;
+	umode_t reparse_mode_type = 0;
 	u32 next = 0;
 
 	switch (tag) {
 	case IO_REPARSE_TAG_LX_SYMLINK:
-		fattr->cf_mode |= S_IFLNK;
+		reparse_mode_type = S_IFLNK;
 		break;
 	case IO_REPARSE_TAG_LX_FIFO:
-		fattr->cf_mode |= S_IFIFO;
+		reparse_mode_type = S_IFIFO;
 		break;
 	case IO_REPARSE_TAG_AF_UNIX:
-		fattr->cf_mode |= S_IFSOCK;
+		reparse_mode_type = S_IFSOCK;
 		break;
 	case IO_REPARSE_TAG_LX_CHR:
-		fattr->cf_mode |= S_IFCHR;
+		reparse_mode_type = S_IFCHR;
 		break;
 	case IO_REPARSE_TAG_LX_BLK:
-		fattr->cf_mode |= S_IFBLK;
+		reparse_mode_type = S_IFBLK;
 		break;
+	default:
+		return false;
 	}
 
+	/*
+	 * When reparse buffer is not available then this is from readdir() call
+	 * which does not provide EAs. readdir() can return DT_UNKNOWN type,
+	 * which is signaled by no filling the fattr->cf_mode and returning true.
+	 */
+	if (!data->reparse.buf && !data->wsl.eas_len)
+		ignore_missing_eas = true;
+
 	if (!data->wsl.eas_len)
 		goto out;
 
@@ -1162,7 +1174,7 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
 			fattr->cf_gid = wsl_make_kgid(cifs_sb, v);
 		else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) {
 			/* File type in reparse point tag and in xattr mode must match. */
-			if (S_DT(fattr->cf_mode) != S_DT(le32_to_cpu(*(__le32 *)v)))
+			if (S_DT(reparse_mode_type) != S_DT(le32_to_cpu(*(__le32 *)v)))
 				return false;
 			fattr->cf_mode = (umode_t)le32_to_cpu(*(__le32 *)v);
 		} else if (!strncmp(name, SMB2_WSL_XATTR_DEV, nlen)) {
@@ -1174,8 +1186,9 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
 
 	/* Major and minor numbers for char and block devices are mandatory. */
 	if (!have_xattr_dev && (tag == IO_REPARSE_TAG_LX_CHR || tag == IO_REPARSE_TAG_LX_BLK))
-		return false;
+		return ignore_missing_eas;
 
+	fattr->cf_mode |= reparse_mode_type;
 	return true;
 }
 
-- 
2.20.1


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

* [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size
  2025-06-08 17:01 [PATCH 0/5] cifs: Fix validation of WSL-style special files Pali Rohár
  2025-06-08 17:01 ` [PATCH 1/5] cifs: Remove duplicate fattr->cf_dtype assignment from wsl_to_fattr() function Pali Rohár
  2025-06-08 17:01 ` [PATCH 2/5] cifs: Fix validation of EAs for WSL reparse points Pali Rohár
@ 2025-06-08 17:01 ` Pali Rohár
  2025-06-08 21:49   ` Paulo Alcantara
  2025-06-08 17:01 ` [PATCH 4/5] cifs: Query EA $LXMOD in cifs_query_path_info() for WSL reparse points Pali Rohár
  2025-06-08 17:01 ` [PATCH 5/5] cifs: Validate presence of EA $LXMOD " Pali Rohár
  4 siblings, 1 reply; 10+ messages in thread
From: Pali Rohár @ 2025-06-08 17:01 UTC (permalink / raw)
  To: Steve French, Paulo Alcantara; +Cc: linux-cifs, linux-kernel

Currently the SMB2_OP_QUERY_WSL_EA checks that response buffer has at least
size SMB2_WSL_MIN_QUERY_EA_RESP_SIZE and maximally it is
SMB2_WSL_MAX_QUERY_EA_RESP_SIZE.

Constant SMB2_WSL_MIN_QUERY_EA_RESP_SIZE is defined wrongly because it
expects that the there are at least 3 EAs. But WSL subsystem has only one
mandatory EA: $LXMOD. So fix the SMB2_WSL_MIN_QUERY_EA_RESP_SIZE to be size
of the structure of one EA.

Relax also SMB2_WSL_MAX_QUERY_EA_RESP_SIZE, calculate maximum size from the
size of the largest EA which is 8 bytes for $LXDEV.

This change allows to recognize WSL CHR and BLK reparse points which have
only $LXMOD and $LXDEV EAs (no $LXUID or $LXGID). WSL subsystem recognize
such reparse points too.

Fixes: ea41367b2a60 ("smb: client: introduce SMB2_OP_QUERY_WSL_EA")
Signed-off-by: Pali Rohár <pali@kernel.org>
---
 fs/smb/client/smb2pdu.h | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
index 3c09a58dfd07..cdf0ab9ddbcd 100644
--- a/fs/smb/client/smb2pdu.h
+++ b/fs/smb/client/smb2pdu.h
@@ -425,24 +425,23 @@ struct smb2_create_ea_ctx {
 #define SMB2_WSL_XATTR_MODE		"$LXMOD"
 #define SMB2_WSL_XATTR_DEV		"$LXDEV"
 #define SMB2_WSL_XATTR_NAME_LEN	6
-#define SMB2_WSL_NUM_XATTRS		4
 
 #define SMB2_WSL_XATTR_UID_SIZE	4
 #define SMB2_WSL_XATTR_GID_SIZE	4
 #define SMB2_WSL_XATTR_MODE_SIZE	4
 #define SMB2_WSL_XATTR_DEV_SIZE	8
 
+/* minimal size: at least the smallest EA has to be present */
 #define SMB2_WSL_MIN_QUERY_EA_RESP_SIZE \
-	(ALIGN((SMB2_WSL_NUM_XATTRS - 1) * \
-	       (SMB2_WSL_XATTR_NAME_LEN + 1 + \
-		sizeof(struct smb2_file_full_ea_info)), 4) + \
-	 SMB2_WSL_XATTR_NAME_LEN + 1 + sizeof(struct smb2_file_full_ea_info))
+	(sizeof(struct smb2_file_full_ea_info) + SMB2_WSL_XATTR_NAME_LEN + 1 + 4)
 
+/*
+ * maximal size: all 4 EAs are present,
+ * beginning of each EA structure has to be aligned to 4 bytes,
+ * EAs have different size and can be returned in any other,
+ * use the largest EA size for aligning when calculating maximal size
+ */
 #define SMB2_WSL_MAX_QUERY_EA_RESP_SIZE \
-	(ALIGN(SMB2_WSL_MIN_QUERY_EA_RESP_SIZE + \
-	       SMB2_WSL_XATTR_UID_SIZE + \
-	       SMB2_WSL_XATTR_GID_SIZE + \
-	       SMB2_WSL_XATTR_MODE_SIZE + \
-	       SMB2_WSL_XATTR_DEV_SIZE, 4))
+	4 * ALIGN((sizeof(struct smb2_file_full_ea_info) + SMB2_WSL_XATTR_NAME_LEN + 1 + 8), 4)
 
 #endif				/* _SMB2PDU_H */
-- 
2.20.1


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

* [PATCH 4/5] cifs: Query EA $LXMOD in cifs_query_path_info() for WSL reparse points
  2025-06-08 17:01 [PATCH 0/5] cifs: Fix validation of WSL-style special files Pali Rohár
                   ` (2 preceding siblings ...)
  2025-06-08 17:01 ` [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size Pali Rohár
@ 2025-06-08 17:01 ` Pali Rohár
  2025-06-08 17:01 ` [PATCH 5/5] cifs: Validate presence of EA $LXMOD " Pali Rohár
  4 siblings, 0 replies; 10+ messages in thread
From: Pali Rohár @ 2025-06-08 17:01 UTC (permalink / raw)
  To: Steve French, Paulo Alcantara; +Cc: linux-cifs, linux-kernel

EA $LXMOD is required for WSL non-symlink reparse points.

Fixes: ef86ab131d91 ("cifs: Fix querying of WSL CHR and BLK reparse points over SMB1")
Signed-off-by: Pali Rohár <pali@kernel.org>
---
 fs/smb/client/smb1ops.c | 62 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 2 deletions(-)

diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index df955cecdd4c..1f9166143ab1 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -659,14 +659,72 @@ static int cifs_query_path_info(const unsigned int xid,
 	}
 
 #ifdef CONFIG_CIFS_XATTR
+	/*
+	 * For non-symlink WSL reparse points it is required to fetch
+	 * EA $LXMOD which contains in its S_DT part the mandatory file type.
+	 */
+	if (!rc && data->reparse_point) {
+		struct smb2_file_full_ea_info *ea;
+		u32 next = 0;
+
+		ea = (struct smb2_file_full_ea_info *)data->wsl.eas;
+		do {
+			ea = (void *)((u8 *)ea + next);
+			next = le32_to_cpu(ea->next_entry_offset);
+		} while (next);
+		if (le16_to_cpu(ea->ea_value_length)) {
+			ea->next_entry_offset = cpu_to_le32(ALIGN(sizeof(*ea) +
+						ea->ea_name_length + 1 +
+						le16_to_cpu(ea->ea_value_length), 4));
+			ea = (void *)((u8 *)ea + le32_to_cpu(ea->next_entry_offset));
+		}
+
+		rc = CIFSSMBQAllEAs(xid, tcon, full_path, SMB2_WSL_XATTR_MODE,
+				    &ea->ea_data[SMB2_WSL_XATTR_NAME_LEN + 1],
+				    SMB2_WSL_XATTR_MODE_SIZE, cifs_sb);
+		if (rc == SMB2_WSL_XATTR_MODE_SIZE) {
+			ea->next_entry_offset = cpu_to_le32(0);
+			ea->flags = 0;
+			ea->ea_name_length = SMB2_WSL_XATTR_NAME_LEN;
+			ea->ea_value_length = cpu_to_le16(SMB2_WSL_XATTR_MODE_SIZE);
+			memcpy(&ea->ea_data[0], SMB2_WSL_XATTR_MODE, SMB2_WSL_XATTR_NAME_LEN + 1);
+			data->wsl.eas_len += ALIGN(sizeof(*ea) + SMB2_WSL_XATTR_NAME_LEN + 1 +
+						   SMB2_WSL_XATTR_MODE_SIZE, 4);
+			rc = 0;
+		} else if (rc >= 0) {
+			/* It is an error if EA $LXMOD has wrong size. */
+			rc = -EINVAL;
+		} else {
+			/*
+			 * In all other cases ignore error if fetching
+			 * of EA $LXMOD failed. It is needed only for
+			 * non-symlink WSL reparse points and wsl_to_fattr()
+			 * handle the case when EA is missing.
+			 */
+			rc = 0;
+		}
+	}
+
 	/*
 	 * For WSL CHR and BLK reparse points it is required to fetch
 	 * EA $LXDEV which contains major and minor device numbers.
 	 */
 	if (!rc && data->reparse_point) {
 		struct smb2_file_full_ea_info *ea;
+		u32 next = 0;
 
 		ea = (struct smb2_file_full_ea_info *)data->wsl.eas;
+		do {
+			ea = (void *)((u8 *)ea + next);
+			next = le32_to_cpu(ea->next_entry_offset);
+		} while (next);
+		if (le16_to_cpu(ea->ea_value_length)) {
+			ea->next_entry_offset = cpu_to_le32(ALIGN(sizeof(*ea) +
+						ea->ea_name_length + 1 +
+						le16_to_cpu(ea->ea_value_length), 4));
+			ea = (void *)((u8 *)ea + le32_to_cpu(ea->next_entry_offset));
+		}
+
 		rc = CIFSSMBQAllEAs(xid, tcon, full_path, SMB2_WSL_XATTR_DEV,
 				    &ea->ea_data[SMB2_WSL_XATTR_NAME_LEN + 1],
 				    SMB2_WSL_XATTR_DEV_SIZE, cifs_sb);
@@ -676,8 +734,8 @@ static int cifs_query_path_info(const unsigned int xid,
 			ea->ea_name_length = SMB2_WSL_XATTR_NAME_LEN;
 			ea->ea_value_length = cpu_to_le16(SMB2_WSL_XATTR_DEV_SIZE);
 			memcpy(&ea->ea_data[0], SMB2_WSL_XATTR_DEV, SMB2_WSL_XATTR_NAME_LEN + 1);
-			data->wsl.eas_len = sizeof(*ea) + SMB2_WSL_XATTR_NAME_LEN + 1 +
-					    SMB2_WSL_XATTR_DEV_SIZE;
+			data->wsl.eas_len += ALIGN(sizeof(*ea) + SMB2_WSL_XATTR_NAME_LEN + 1 +
+						   SMB2_WSL_XATTR_MODE_SIZE, 4);
 			rc = 0;
 		} else if (rc >= 0) {
 			/* It is an error if EA $LXDEV has wrong size. */
-- 
2.20.1


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

* [PATCH 5/5] cifs: Validate presence of EA $LXMOD for WSL reparse points
  2025-06-08 17:01 [PATCH 0/5] cifs: Fix validation of WSL-style special files Pali Rohár
                   ` (3 preceding siblings ...)
  2025-06-08 17:01 ` [PATCH 4/5] cifs: Query EA $LXMOD in cifs_query_path_info() for WSL reparse points Pali Rohár
@ 2025-06-08 17:01 ` Pali Rohár
  4 siblings, 0 replies; 10+ messages in thread
From: Pali Rohár @ 2025-06-08 17:01 UTC (permalink / raw)
  To: Steve French, Paulo Alcantara; +Cc: linux-cifs, linux-kernel

S_DT part of EA $LXMOD is mandatory for all WSL reparse points except the
WSL symlink and Win32 socket. Microsoft WSL subsystem does not recognize
them without EA $LXMOD too, and treat such inodes as regular files.

Fixes: ef201e8759d2 ("cifs: Validate EAs for WSL reparse points")
Fixes: 78e26bec4d6d ("smb: client: parse uid, gid, mode and dev from WSL reparse points")
Signed-off-by: Pali Rohár <pali@kernel.org>
---
 fs/smb/client/reparse.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
index 8d989e436517..3dffd5f0dc07 100644
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -1118,6 +1118,7 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
 {
 	struct smb2_file_full_ea_info *ea;
 	bool ignore_missing_eas = false;
+	bool have_xattr_mode = false;
 	bool have_xattr_dev = false;
 	umode_t reparse_mode_type = 0;
 	u32 next = 0;
@@ -1177,6 +1178,7 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
 			if (S_DT(reparse_mode_type) != S_DT(le32_to_cpu(*(__le32 *)v)))
 				return false;
 			fattr->cf_mode = (umode_t)le32_to_cpu(*(__le32 *)v);
+			have_xattr_mode = true;
 		} else if (!strncmp(name, SMB2_WSL_XATTR_DEV, nlen)) {
 			fattr->cf_rdev = reparse_mkdev(v);
 			have_xattr_dev = true;
@@ -1188,6 +1190,16 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
 	if (!have_xattr_dev && (tag == IO_REPARSE_TAG_LX_CHR || tag == IO_REPARSE_TAG_LX_BLK))
 		return ignore_missing_eas;
 
+	/*
+	 * S_DT part of xattr MODE is mandatory for all WSL reparse points except the WSL symlink.
+	 * Microsoft WSL does not recognize them without xattr MODE too (except the WSL symlink).
+	 * IO_REPARSE_TAG_AF_UNIX is here an exception because this reparse point is used by both
+	 * WSL subsystem and native NT/WinAPI subsystems. And NT/WinAPI creates AF UNIX socket
+	 * without the xattr MODE and recognize it also without the xattr MODE.
+	 */
+	if (!have_xattr_mode && (tag != IO_REPARSE_TAG_AF_UNIX && tag != IO_REPARSE_TAG_LX_SYMLINK))
+		return ignore_missing_eas;
+
 	fattr->cf_mode |= reparse_mode_type;
 	return true;
 }
-- 
2.20.1


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

* Re: [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size
  2025-06-08 17:01 ` [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size Pali Rohár
@ 2025-06-08 21:49   ` Paulo Alcantara
  2025-06-08 22:15     ` Pali Rohár
  0 siblings, 1 reply; 10+ messages in thread
From: Paulo Alcantara @ 2025-06-08 21:49 UTC (permalink / raw)
  To: Pali Rohár, Steve French; +Cc: linux-cifs, linux-kernel

Pali Rohár <pali@kernel.org> writes:

> Currently the SMB2_OP_QUERY_WSL_EA checks that response buffer has at least
> size SMB2_WSL_MIN_QUERY_EA_RESP_SIZE and maximally it is
> SMB2_WSL_MAX_QUERY_EA_RESP_SIZE.
>
> Constant SMB2_WSL_MIN_QUERY_EA_RESP_SIZE is defined wrongly because it
> expects that the there are at least 3 EAs. But WSL subsystem has only one
> mandatory EA: $LXMOD. So fix the SMB2_WSL_MIN_QUERY_EA_RESP_SIZE to be size
> of the structure of one EA.
>
> Relax also SMB2_WSL_MAX_QUERY_EA_RESP_SIZE, calculate maximum size from the
> size of the largest EA which is 8 bytes for $LXDEV.
>
> This change allows to recognize WSL CHR and BLK reparse points which have
> only $LXMOD and $LXDEV EAs (no $LXUID or $LXGID). WSL subsystem recognize
> such reparse points too.
>
> Fixes: ea41367b2a60 ("smb: client: introduce SMB2_OP_QUERY_WSL_EA")
> Signed-off-by: Pali Rohár <pali@kernel.org>
> ---
>  fs/smb/client/smb2pdu.h | 19 +++++++++----------
>  1 file changed, 9 insertions(+), 10 deletions(-)

If we're querying all those EAs and the file has only $LXMOD, wouldn't
the server return empty EAs except for $LXMOD?

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

* Re: [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size
  2025-06-08 21:49   ` Paulo Alcantara
@ 2025-06-08 22:15     ` Pali Rohár
  2025-06-08 23:10       ` Paulo Alcantara
  0 siblings, 1 reply; 10+ messages in thread
From: Pali Rohár @ 2025-06-08 22:15 UTC (permalink / raw)
  To: Paulo Alcantara; +Cc: Steve French, linux-cifs, linux-kernel

On Sunday 08 June 2025 18:49:43 Paulo Alcantara wrote:
> Pali Rohár <pali@kernel.org> writes:
> 
> > Currently the SMB2_OP_QUERY_WSL_EA checks that response buffer has at least
> > size SMB2_WSL_MIN_QUERY_EA_RESP_SIZE and maximally it is
> > SMB2_WSL_MAX_QUERY_EA_RESP_SIZE.
> >
> > Constant SMB2_WSL_MIN_QUERY_EA_RESP_SIZE is defined wrongly because it
> > expects that the there are at least 3 EAs. But WSL subsystem has only one
> > mandatory EA: $LXMOD. So fix the SMB2_WSL_MIN_QUERY_EA_RESP_SIZE to be size
> > of the structure of one EA.
> >
> > Relax also SMB2_WSL_MAX_QUERY_EA_RESP_SIZE, calculate maximum size from the
> > size of the largest EA which is 8 bytes for $LXDEV.
> >
> > This change allows to recognize WSL CHR and BLK reparse points which have
> > only $LXMOD and $LXDEV EAs (no $LXUID or $LXGID). WSL subsystem recognize
> > such reparse points too.
> >
> > Fixes: ea41367b2a60 ("smb: client: introduce SMB2_OP_QUERY_WSL_EA")
> > Signed-off-by: Pali Rohár <pali@kernel.org>
> > ---
> >  fs/smb/client/smb2pdu.h | 19 +++++++++----------
> >  1 file changed, 9 insertions(+), 10 deletions(-)
> 
> If we're querying all those EAs and the file has only $LXMOD, wouldn't
> the server return empty EAs except for $LXMOD?

We are using FILE_FULL_EA_INFORMATION for querying EAs, which means that
always all stored EAs are returned. It is not 4 calls (one by one), but
rather one call to return everything at once.

Windows server in this case returns just one EA in its response: $LXMOD EA.
And SMB2_WSL_MIN_QUERY_EA_RESP_SIZE specifies that at least 3 EAs must
be returned, otherwise check_wsl_eas() throws error and do not try to
parse response.

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

* Re: [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size
  2025-06-08 22:15     ` Pali Rohár
@ 2025-06-08 23:10       ` Paulo Alcantara
  2025-06-09 22:49         ` Pali Rohár
  0 siblings, 1 reply; 10+ messages in thread
From: Paulo Alcantara @ 2025-06-08 23:10 UTC (permalink / raw)
  To: Pali Rohár; +Cc: Steve French, linux-cifs, linux-kernel

Pali Rohár <pali@kernel.org> writes:

> On Sunday 08 June 2025 18:49:43 Paulo Alcantara wrote:
>> Pali Rohár <pali@kernel.org> writes:
>> 
>> If we're querying all those EAs and the file has only $LXMOD, wouldn't
>> the server return empty EAs except for $LXMOD?
>
> We are using FILE_FULL_EA_INFORMATION for querying EAs, which means that
> always all stored EAs are returned. It is not 4 calls (one by one), but
> rather one call to return everything at once.

Yes.

> Windows server in this case returns just one EA in its response: $LXMOD EA.
> And SMB2_WSL_MIN_QUERY_EA_RESP_SIZE specifies that at least 3 EAs must
> be returned, otherwise check_wsl_eas() throws error and do not try to
> parse response.

Can you share a trace of the server returning only a single EA in the
response when we query $LXUID, $LXGID, $LXMOD and $LXDEV?

What I mean is that we query all those EAs when we find reparse points
on non-POSIX mounts, and if the file doesn't have them, the server still
returns the EAs but with a zero smb2_file_full_ea_info::ea_value_len.
check_wsl_eas() skips the EA when is @vlen zero.

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

* Re: [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size
  2025-06-08 23:10       ` Paulo Alcantara
@ 2025-06-09 22:49         ` Pali Rohár
  0 siblings, 0 replies; 10+ messages in thread
From: Pali Rohár @ 2025-06-09 22:49 UTC (permalink / raw)
  To: Paulo Alcantara; +Cc: Steve French, linux-cifs, linux-kernel

On Sunday 08 June 2025 20:10:24 Paulo Alcantara wrote:
> Pali Rohár <pali@kernel.org> writes:
> 
> > On Sunday 08 June 2025 18:49:43 Paulo Alcantara wrote:
> >> Pali Rohár <pali@kernel.org> writes:
> >> 
> >> If we're querying all those EAs and the file has only $LXMOD, wouldn't
> >> the server return empty EAs except for $LXMOD?
> >
> > We are using FILE_FULL_EA_INFORMATION for querying EAs, which means that
> > always all stored EAs are returned. It is not 4 calls (one by one), but
> > rather one call to return everything at once.
> 
> Yes.
> 
> > Windows server in this case returns just one EA in its response: $LXMOD EA.
> > And SMB2_WSL_MIN_QUERY_EA_RESP_SIZE specifies that at least 3 EAs must
> > be returned, otherwise check_wsl_eas() throws error and do not try to
> > parse response.
> 
> Can you share a trace of the server returning only a single EA in the
> response when we query $LXUID, $LXGID, $LXMOD and $LXDEV?
> 
> What I mean is that we query all those EAs when we find reparse points
> on non-POSIX mounts, and if the file doesn't have them, the server still
> returns the EAs but with a zero smb2_file_full_ea_info::ea_value_len.
> check_wsl_eas() skips the EA when is @vlen zero.

I started recording of tcpdump and I'm not able to reproduce it anymore.
That is stupid. So I started investigation what happened there...

And the result is that I have more changes related to EAs on my disk,
and I did some tests on all of them. And due to bug in dissector of
older wireshark version which I used, I wrongly interpreted the format
of network EA buffer. So based on this I calculated all sizes wrongly
and introduced bug in my WIP code on my disk. So it my mistake here.

So please drop this one "PATCH 3/5". I re-checked the size limits and
they should be correct.

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

end of thread, other threads:[~2025-06-09 22:49 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-08 17:01 [PATCH 0/5] cifs: Fix validation of WSL-style special files Pali Rohár
2025-06-08 17:01 ` [PATCH 1/5] cifs: Remove duplicate fattr->cf_dtype assignment from wsl_to_fattr() function Pali Rohár
2025-06-08 17:01 ` [PATCH 2/5] cifs: Fix validation of EAs for WSL reparse points Pali Rohár
2025-06-08 17:01 ` [PATCH 3/5] cifs: Fix validation of SMB2_OP_QUERY_WSL_EA response size Pali Rohár
2025-06-08 21:49   ` Paulo Alcantara
2025-06-08 22:15     ` Pali Rohár
2025-06-08 23:10       ` Paulo Alcantara
2025-06-09 22:49         ` Pali Rohár
2025-06-08 17:01 ` [PATCH 4/5] cifs: Query EA $LXMOD in cifs_query_path_info() for WSL reparse points Pali Rohár
2025-06-08 17:01 ` [PATCH 5/5] cifs: Validate presence of EA $LXMOD " Pali Rohár

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 NNTP newsgroup(s).