From: Pali Rohár pali@kernel.org
[ Upstream commit b460249b9a1dab7a9f58483e5349d045ad6d585c ]
To query root path (without msearch wildcard) it is needed to send pattern '' instead of '' (empty string).
This allows to use CIFSFindFirst() to query information about root path which is being used in followup changes.
This change fixes the stat() syscall called on the root path on the mount. It is because stat() syscall uses the cifs_query_path_info() function and it can fallback to the CIFSFindFirst() usage with msearch=false.
Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Based on my analysis of the commit and the kernel code, here's my assessment:
**Backport Status: YES**
This commit should be backported to stable kernel trees for the following reasons:
## Bug Fix Analysis
1. **Fixes a real user-visible bug**: The commit explicitly states it "fixes the stat() syscall called on the root path on the mount". This is a fundamental filesystem operation that users and applications rely on. When `stat()` fails on the mount root, it can break many applications that query filesystem metadata.
2. **Small and contained change**: The fix is minimal - it only adds two small conditional blocks (lines 4023-4026 for Unicode and lines 4035-4038 for non-Unicode) that handle the special case when `searchName` is empty (root path) and `msearch` is false.
3. **Clear bug mechanism**: The code shows that when querying the root path without wildcard search (`msearch=false`), the function was sending an empty string instead of the required `` pattern. This is evident from the fallback path in `cifs_query_path_info()` at line 586-588 which calls `CIFSFindFirst()` with `false` for the msearch parameter.
4. **Low regression risk**: The change only affects the specific case where: - `searchName` is empty (root path query) - `msearch` is false (no wildcard search) - This doesn't change any existing behavior for non-root paths
5. **Follows stable kernel rules**: This is a clear bug fix that: - Fixes a real bug that users can hit - Is not a theoretical race condition - Has minimal lines of code changed - Doesn't introduce new features - Is isolated to the CIFS/SMB subsystem
6. **Critical path functionality**: The `stat()` syscall is fundamental to filesystem operations. Many applications depend on being able to query metadata about the filesystem root. This failure could cause mount verification scripts, filesystem monitoring tools, and other utilities to fail.
## Technical Details
The fix handles both Unicode and non-Unicode cases by setting the FileName field to contain the directory separator (``) when the search path is empty, ensuring the SMB protocol receives the correct pattern for querying the root directory. This aligns with SMB protocol requirements where an empty path is not valid for directory queries but `` represents the root.
The commit message clearly identifies this as fixing existing functionality rather than adding new features, making it an ideal candidate for stable backporting according to the stable kernel rules.
fs/smb/client/cifssmb.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index 75142f49d65d..3b6bc53ee1c4 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -4020,6 +4020,12 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, pSMB->FileName[name_len] = 0; pSMB->FileName[name_len+1] = 0; name_len += 2; + } else if (!searchName[0]) { + pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb); + pSMB->FileName[1] = 0; + pSMB->FileName[2] = 0; + pSMB->FileName[3] = 0; + name_len = 4; } } else { name_len = copy_path_name(pSMB->FileName, searchName); @@ -4031,6 +4037,10 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, pSMB->FileName[name_len] = '*'; pSMB->FileName[name_len+1] = 0; name_len += 2; + } else if (!searchName[0]) { + pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb); + pSMB->FileName[1] = 0; + name_len = 2; } }