[PATCH] cifs: Check for UTF-16 null codepoint in SFU symlink target location

Pali Rohár posted 1 patch 2 months ago
fs/smb/client/inode.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
[PATCH] cifs: Check for UTF-16 null codepoint in SFU symlink target location
Posted by Pali Rohár 2 months ago
Check that read buffer of SFU symlink target location does not contain
UTF-16 null codepoint (via UniStrnlen() call) because Linux cannot process
symlink with null byte, it truncates everything in buffer after null byte.

Fixes: cf2ce67345d6 ("cifs: Add support for reading SFU symlink location")
Signed-off-by: Pali Rohár <pali@kernel.org>
---
 fs/smb/client/inode.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index 88c4c3d0d607..0c23634438e5 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -625,10 +625,16 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
 									       &symlink_len_utf16,
 									       &symlink_buf_utf16,
 									       &buf_type);
+					/*
+					 * Check that read buffer has valid length and does not
+					 * contain UTF-16 null codepoint (via UniStrnlen() call)
+					 * because Linux cannot process symlink with null byte.
+					 */
 					if ((rc == 0) &&
 					    (symlink_len_utf16 > 0) &&
 					    (symlink_len_utf16 < fattr->cf_eof-8 + 1) &&
-					    (symlink_len_utf16 % 2 == 0)) {
+					    (symlink_len_utf16 % 2 == 0) &&
+					    (UniStrnlen((wchar_t *)symlink_buf_utf16, symlink_len_utf16/2) == symlink_len_utf16/2)) {
 						fattr->cf_symlink_target =
 							cifs_strndup_from_utf16(symlink_buf_utf16,
 										symlink_len_utf16,
-- 
2.20.1