Patch "ksmbd: casefold utf-8 share names and fix ascii lowercase conversion" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ksmbd: casefold utf-8 share names and fix ascii lowercase conversion

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     ksmbd-casefold-utf-8-share-names-and-fix-ascii-lowercase-conversion.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.


>From linkinjeon@xxxxxxxxx Mon Dec 18 16:38:13 2023
From: Namjae Jeon <linkinjeon@xxxxxxxxxx>
Date: Tue, 19 Dec 2023 00:33:12 +0900
Subject: ksmbd: casefold utf-8 share names and fix ascii lowercase conversion
To: gregkh@xxxxxxxxxxxxxxxxxxx, stable@xxxxxxxxxxxxxxx
Cc: smfrench@xxxxxxxxx, "Atte Heikkilä" <atteh.mailbox@xxxxxxxxx>, "Namjae Jeon" <linkinjeon@xxxxxxxxxx>, "Steve French" <stfrench@xxxxxxxxxxxxx>
Message-ID: <20231218153454.8090-53-linkinjeon@xxxxxxxxxx>

From: Atte Heikkilä <atteh.mailbox@xxxxxxxxx>

[ Upstream commit 16b5f54e30c1ddec36bdf946a299b3254aace477 ]

strtolower() corrupts all UTF-8 share names that have a byte in the C0
(Ã? ISO8859-1) to DE (Ã? ISO8859-1) range, since the non-ASCII part of
ISO8859-1 is incompatible with UTF-8. Prevent this by checking that a
byte is in the ASCII range with isascii(), before the conversion to
lowercase with tolower(). Properly handle case-insensitivity of UTF-8
share names by casefolding them, but fallback to ASCII lowercase
conversion on failure or if CONFIG_UNICODE is not set. Refactor to move
the share name casefolding immediately after the share name extraction.
Also, make the associated constness corrections.

Signed-off-by: Atte Heikkilä <atteh.mailbox@xxxxxxxxx>
Acked-by: Namjae Jeon <linkinjeon@xxxxxxxxxx>
Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 fs/ksmbd/connection.c        |    8 +++++++
 fs/ksmbd/connection.h        |    1 
 fs/ksmbd/mgmt/share_config.c |   18 +++--------------
 fs/ksmbd/mgmt/share_config.h |    2 -
 fs/ksmbd/mgmt/tree_connect.c |    2 -
 fs/ksmbd/mgmt/tree_connect.h |    2 -
 fs/ksmbd/misc.c              |   44 +++++++++++++++++++++++++++++++++++--------
 fs/ksmbd/misc.h              |    2 -
 fs/ksmbd/smb2pdu.c           |    2 -
 fs/ksmbd/unicode.h           |    3 +-
 10 files changed, 56 insertions(+), 28 deletions(-)

--- a/fs/ksmbd/connection.c
+++ b/fs/ksmbd/connection.c
@@ -60,6 +60,12 @@ struct ksmbd_conn *ksmbd_conn_alloc(void
 	conn->local_nls = load_nls("utf8");
 	if (!conn->local_nls)
 		conn->local_nls = load_nls_default();
+	if (IS_ENABLED(CONFIG_UNICODE))
+		conn->um = utf8_load("12.1.0");
+	else
+		conn->um = ERR_PTR(-EOPNOTSUPP);
+	if (IS_ERR(conn->um))
+		conn->um = NULL;
 	atomic_set(&conn->req_running, 0);
 	atomic_set(&conn->r_count, 0);
 	conn->total_credits = 1;
@@ -361,6 +367,8 @@ out:
 	wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0);
 
 
+	if (IS_ENABLED(CONFIG_UNICODE))
+		utf8_unload(conn->um);
 	unload_nls(conn->local_nls);
 	if (default_conn_ops.terminate_fn)
 		default_conn_ops.terminate_fn(conn);
--- a/fs/ksmbd/connection.h
+++ b/fs/ksmbd/connection.h
@@ -46,6 +46,7 @@ struct ksmbd_conn {
 	char				*request_buf;
 	struct ksmbd_transport		*transport;
 	struct nls_table		*local_nls;
+	struct unicode_map		*um;
 	struct list_head		conns_list;
 	/* smb session 1 per user */
 	struct xarray			sessions;
--- a/fs/ksmbd/mgmt/share_config.c
+++ b/fs/ksmbd/mgmt/share_config.c
@@ -26,7 +26,7 @@ struct ksmbd_veto_pattern {
 	struct list_head	list;
 };
 
-static unsigned int share_name_hash(char *name)
+static unsigned int share_name_hash(const char *name)
 {
 	return jhash(name, strlen(name), 0);
 }
@@ -72,7 +72,7 @@ __get_share_config(struct ksmbd_share_co
 	return share;
 }
 
-static struct ksmbd_share_config *__share_lookup(char *name)
+static struct ksmbd_share_config *__share_lookup(const char *name)
 {
 	struct ksmbd_share_config *share;
 	unsigned int key = share_name_hash(name);
@@ -119,7 +119,7 @@ static int parse_veto_list(struct ksmbd_
 	return 0;
 }
 
-static struct ksmbd_share_config *share_config_request(char *name)
+static struct ksmbd_share_config *share_config_request(const char *name)
 {
 	struct ksmbd_share_config_response *resp;
 	struct ksmbd_share_config *share = NULL;
@@ -190,20 +190,10 @@ out:
 	return share;
 }
 
-static void strtolower(char *share_name)
-{
-	while (*share_name) {
-		*share_name = tolower(*share_name);
-		share_name++;
-	}
-}
-
-struct ksmbd_share_config *ksmbd_share_config_get(char *name)
+struct ksmbd_share_config *ksmbd_share_config_get(const char *name)
 {
 	struct ksmbd_share_config *share;
 
-	strtolower(name);
-
 	down_read(&shares_table_lock);
 	share = __share_lookup(name);
 	if (share)
--- a/fs/ksmbd/mgmt/share_config.h
+++ b/fs/ksmbd/mgmt/share_config.h
@@ -74,7 +74,7 @@ static inline void ksmbd_share_config_pu
 	__ksmbd_share_config_put(share);
 }
 
-struct ksmbd_share_config *ksmbd_share_config_get(char *name);
+struct ksmbd_share_config *ksmbd_share_config_get(const char *name);
 bool ksmbd_share_veto_filename(struct ksmbd_share_config *share,
 			       const char *filename);
 #endif /* __SHARE_CONFIG_MANAGEMENT_H__ */
--- a/fs/ksmbd/mgmt/tree_connect.c
+++ b/fs/ksmbd/mgmt/tree_connect.c
@@ -17,7 +17,7 @@
 
 struct ksmbd_tree_conn_status
 ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
-			char *share_name)
+			const char *share_name)
 {
 	struct ksmbd_tree_conn_status status = {-ENOENT, NULL};
 	struct ksmbd_tree_connect_response *resp = NULL;
--- a/fs/ksmbd/mgmt/tree_connect.h
+++ b/fs/ksmbd/mgmt/tree_connect.h
@@ -42,7 +42,7 @@ struct ksmbd_session;
 
 struct ksmbd_tree_conn_status
 ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
-			char *share_name);
+			const char *share_name);
 
 int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
 			       struct ksmbd_tree_connect *tree_conn);
--- a/fs/ksmbd/misc.c
+++ b/fs/ksmbd/misc.c
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/xattr.h>
 #include <linux/fs.h>
+#include <linux/unicode.h>
 
 #include "misc.h"
 #include "smb_common.h"
@@ -226,26 +227,53 @@ void ksmbd_conv_path_to_windows(char *pa
 	strreplace(path, '/', '\\');
 }
 
+static char *casefold_sharename(struct unicode_map *um, const char *name)
+{
+	char *cf_name;
+	int cf_len;
+
+	cf_name = kzalloc(KSMBD_REQ_MAX_SHARE_NAME, GFP_KERNEL);
+	if (!cf_name)
+		return ERR_PTR(-ENOMEM);
+
+	if (IS_ENABLED(CONFIG_UNICODE) && um) {
+		const struct qstr q_name = {.name = name, .len = strlen(name)};
+
+		cf_len = utf8_casefold(um, &q_name, cf_name,
+				       KSMBD_REQ_MAX_SHARE_NAME);
+		if (cf_len < 0)
+			goto out_ascii;
+
+		return cf_name;
+	}
+
+out_ascii:
+	cf_len = strscpy(cf_name, name, KSMBD_REQ_MAX_SHARE_NAME);
+	if (cf_len < 0) {
+		kfree(cf_name);
+		return ERR_PTR(-E2BIG);
+	}
+
+	for (; *cf_name; ++cf_name)
+		*cf_name = isascii(*cf_name) ? tolower(*cf_name) : *cf_name;
+	return cf_name - cf_len;
+}
+
 /**
  * ksmbd_extract_sharename() - get share name from tree connect request
  * @treename:	buffer containing tree name and share name
  *
  * Return:      share name on success, otherwise error
  */
-char *ksmbd_extract_sharename(char *treename)
+char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename)
 {
-	char *name = treename;
-	char *dst;
-	char *pos = strrchr(name, '\\');
+	const char *name = treename, *pos = strrchr(name, '\\');
 
 	if (pos)
 		name = (pos + 1);
 
 	/* caller has to free the memory */
-	dst = kstrdup(name, GFP_KERNEL);
-	if (!dst)
-		return ERR_PTR(-ENOMEM);
-	return dst;
+	return casefold_sharename(um, name);
 }
 
 /**
--- a/fs/ksmbd/misc.h
+++ b/fs/ksmbd/misc.h
@@ -20,7 +20,7 @@ int get_nlink(struct kstat *st);
 void ksmbd_conv_path_to_unix(char *path);
 void ksmbd_strip_last_slash(char *path);
 void ksmbd_conv_path_to_windows(char *path);
-char *ksmbd_extract_sharename(char *treename);
+char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename);
 char *convert_to_unix_name(struct ksmbd_share_config *share, const char *name);
 
 #define KSMBD_DIR_INFO_ALIGNMENT	8
--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -1924,7 +1924,7 @@ int smb2_tree_connect(struct ksmbd_work
 		goto out_err1;
 	}
 
-	name = ksmbd_extract_sharename(treename);
+	name = ksmbd_extract_sharename(conn->um, treename);
 	if (IS_ERR(name)) {
 		status.ret = KSMBD_TREE_CONN_STATUS_ERROR;
 		goto out_err1;
--- a/fs/ksmbd/unicode.h
+++ b/fs/ksmbd/unicode.h
@@ -24,6 +24,7 @@
 #include <asm/byteorder.h>
 #include <linux/types.h>
 #include <linux/nls.h>
+#include <linux/unicode.h>
 
 #define  UNIUPR_NOLOWER		/* Example to not expand lower case tables */
 
@@ -69,7 +70,7 @@ char *smb_strndup_from_utf16(const char
 			     const struct nls_table *codepage);
 int smbConvertToUTF16(__le16 *target, const char *source, int srclen,
 		      const struct nls_table *cp, int mapchars);
-char *ksmbd_extract_sharename(char *treename);
+char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename);
 #endif
 
 /*


Patches currently in stable-queue which might be from linkinjeon@xxxxxxxxx are

queue-5.15/ksmbd-fix-uaf-issue-from-opinfo-conn.patch
queue-5.15/ksmbd-fix-race-condition-from-parallel-smb2-lock-requests.patch
queue-5.15/ksmbd-validate-session-id-and-tree-id-in-compound-request.patch
queue-5.15/ksmbd-reorganize-ksmbd_iov_pin_rsp.patch
queue-5.15/ksmbd-convert-to-use-sysfs_emit-sysfs_emit_at-apis.patch
queue-5.15/ksmbd-validate-length-in-smb2_write.patch
queue-5.15/ksmbd-add-support-for-key-exchange.patch
queue-5.15/ksmbd-request-update-to-stale-share-config.patch
queue-5.15/ksmbd-remove-generic_fillattr-use-in-smb2_open.patch
queue-5.15/ksmbd-fix-uninitialized-pointer-read-in-smb2_create_link.patch
queue-5.15/ksmbd-set-smb2_session_flag_encrypt_data-when-enforcing-data-encryption-for-this-share.patch
queue-5.15/ksmbd-constify-struct-path.patch
queue-5.15/ksmbd-casefold-utf-8-share-names-and-fix-ascii-lowercase-conversion.patch
queue-5.15/ksmbd-validate-smb-request-protocol-id.patch
queue-5.15/ksmbd-avoid-out-of-bounds-access-in-decode_preauth_ctxt.patch
queue-5.15/ksmbd-release-interim-response-after-sending-status-pending-response.patch
queue-5.15/ksmbd-fix-racy-issue-under-cocurrent-smb2-tree-disconnect.patch
queue-5.15/ksmbd-fix-out-of-bounds-read-in-smb2_sess_setup.patch
queue-5.15/ksmbd-decrease-the-number-of-smb3-smbdirect-server-sges.patch
queue-5.15/ksmbd-make-utf-8-file-name-comparison-work-in-__caseless_lookup.patch
queue-5.15/ksmbd-use-f_setlk-when-unlocking-a-file.patch
queue-5.15/fs-introduce-lock_rename_child-helper.patch
queue-5.15/ksmbd-use-kzalloc-instead-of-__gfp_zero.patch
queue-5.15/ksmbd-set-ntlmssp_negotiate_seal-flag-to-challenge-blob.patch
queue-5.15/ksmbd-call-ib_drain_qp-when-disconnected.patch
queue-5.15/ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch
queue-5.15/ksmbd-destroy-expired-sessions.patch
queue-5.15/ksmbd-fix-resource-leak-in-smb2_lock.patch
queue-5.15/ksmbd-check-iov-vector-index-in-ksmbd_conn_write.patch
queue-5.15/ksmbd-hide-socket-error-message-when-ipv6-config-is-disable.patch
queue-5.15/ksmbd-use-netif_is_bridge_port.patch
queue-5.15/ksmbd-smbd-simplify-tracking-pending-packets.patch
queue-5.15/ksmbd-implements-sess-rpc_handle_list-as-xarray.patch
queue-5.15/ksmbd-remove-duplicate-flag-set-in-smb2_write.patch
queue-5.15/ksmbd-separately-allocate-ci-per-dentry.patch
queue-5.15/ksmbd-fix-racy-issue-from-session-setup-and-logoff.patch
queue-5.15/ksmbd-fix-race-condition-between-session-lookup-and-expire.patch
queue-5.15/ksmbd-fix-wrong-smbd-max-read-write-size-check.patch
queue-5.15/ksmbd-replace-usage-of-found-with-dedicated-list-iterator-variable.patch
queue-5.15/ksmbd-add-support-for-surrogate-pair-conversion.patch
queue-5.15/ksmbd-reduce-server-smbdirect-max-send-receive-segment-sizes.patch
queue-5.15/ksmbd-fix-force-create-mode-and-force-directory-mode.patch
queue-5.15/ksmbd-remove-unneeded-mark_inode_dirty-in-set_info_sec.patch
queue-5.15/ksmbd-fix-potential-double-free-on-smb2_read_pipe-error-path.patch
queue-5.15/ksmbd-remove-unused-ksmbd_tree_conn_share-function.patch
queue-5.15/ksmbd-block-asynchronous-requests-when-making-a-delay-on-session-setup.patch
queue-5.15/ksmbd-call-putname-after-using-the-last-component.patch
queue-5.15/ksmbd-don-t-open-code-file_path.patch
queue-5.15/ksmbd-fix-passing-freed-memory-aux_payload_buf.patch
queue-5.15/ksmbd-fill-sids-in-smb_find_file_posix_info-response.patch
queue-5.15/ksmbd-don-t-open-code-pd.patch
queue-5.15/ksmbd-shorten-experimental-warning-on-loading-the-module.patch
queue-5.15/ksmbd-remove-filename-in-ksmbd_file.patch
queue-5.15/ksmbd-move-oplock-handling-after-unlock-parent-dir.patch
queue-5.15/ksmbd-fix-race-condition-between-tree-conn-lookup-and-disconnect.patch
queue-5.15/ksmbd-smbd-introduce-read-write-credits-for-rdma-read-write.patch
queue-5.15/ksmbd-fix-slab-out-of-bounds-in-init_smb2_rsp_hdr.patch
queue-5.15/ksmbd-fix-recursive-locking-in-vfs-helpers.patch
queue-5.15/ksmbd-fix-some-kernel-doc-comments.patch
queue-5.15/ksmbd-use-struct_size-helper-in-ksmbd_negotiate_smb_dialect.patch
queue-5.15/ksmbd-smbd-relax-the-count-of-sges-required.patch
queue-5.15/ksmbd-fix-wrong-error-response-status-by-using-set_smb2_rsp_status.patch
queue-5.15/ksmbd-fix-spelling-mistake-excceed-exceeded.patch
queue-5.15/ksmbd-fix-null-pointer-dereferences-in-ksmbd_update_fstate.patch
queue-5.15/ksmbd-fix-encryption-failure-issue-for-session-logoff-response.patch
queue-5.15/ksmbd-prevent-memory-leak-on-error-return.patch
queue-5.15/ksmbd-fix-racy-issue-from-using-d_parent-and-d_name.patch
queue-5.15/ksmbd-change-security-id-to-the-one-samba-used-for-posix-extension.patch
queue-5.15/ksmbd-handle-malformed-smb1-message.patch
queue-5.15/ksmbd-don-t-update-op_state-as-oplock_state_none-on-error.patch
queue-5.15/ksmbd-smbd-fix-connection-dropped-issue.patch
queue-5.15/ksmbd-fix-racy-issue-from-smb2-close-and-logoff-with-multichannel.patch
queue-5.15/ksmbd-change-the-return-value-of-ksmbd_vfs_query_maximal_access-to-void.patch
queue-5.15/ksmbd-fix-slub-overflow-in-ksmbd_decode_ntlmssp_auth_blob.patch
queue-5.15/ksmbd-replace-one-element-array-with-flexible-array-member.patch
queue-5.15/ksmbd-fix-uninitialized-pointer-read-in-ksmbd_vfs_rename.patch
queue-5.15/ksmbd-replace-one-element-arrays-with-flexible-array-members.patch
queue-5.15/ksmbd-fix-unsigned-expression-compared-with-zero.patch
queue-5.15/ksmbd-implements-sess-ksmbd_chann_list-as-xarray.patch
queue-5.15/ksmbd-set-file-permission-mode-to-match-samba-server-posix-extension-behavior.patch
queue-5.15/ksmbd-fix-wrong-interim-response-on-compound.patch
queue-5.15/ksmbd-return-invalid-parameter-error-response-if-smb2-request-is-invalid.patch
queue-5.15/ksmbd-smbd-validate-buffer-descriptor-structures.patch
queue-5.15/ksmbd-fix-missing-rdma-capable-flag-for-ipoib-device-in-ksmbd_rdma_capable_netdev.patch
queue-5.15/ksmbd-send-proper-error-response-in-smb2_tree_connect.patch
queue-5.15/ksmbd-set-negotiatecontextcount-once-instead-of-every-inc.patch
queue-5.15/ksmbd-fix-typo-syncronous-synchronous.patch
queue-5.15/ksmbd-validate-share-name-from-share-config-response.patch
queue-5.15/ksmbd-fix-possible-deadlock-in-smb2_open.patch
queue-5.15/ksmbd-fix-multiple-out-of-bounds-read-during-context-decoding.patch
queue-5.15/ksmbd-add-missing-calling-smb2_set_err_rsp-on-error.patch
queue-5.15/ksmbd-remove-unused-ksmbd_share_configs_cleanup-function.patch
queue-5.15/ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch
queue-5.15/ksmbd-remove-duplicated-codes.patch
queue-5.15/ksmbd-remove-a-redundant-zeroing-of-memory.patch
queue-5.15/ksmbd-change-leasekey-data-type-to-u8-array.patch
queue-5.15/ksmbd-add-support-for-read-compound.patch
queue-5.15/ksmbd-fix-kernel-doc-comment-of-ksmbd_vfs_setxattr.patch
queue-5.15/ksmbd-remove-unused-compression-negotiate-ctx-packing.patch
queue-5.15/ksmbd-switch-to-use-kmemdup_nul-helper.patch
queue-5.15/ksmbd-fix-race-condition-from-parallel-smb2-logoff-requests.patch
queue-5.15/ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch
queue-5.15/ksmbd-remove-unnecessary-generic_fillattr-in-smb2_open.patch
queue-5.15/ksmbd-avoid-duplicate-negotiate-ctx-offset-increments.patch
queue-5.15/ksmbd-remove-experimental-warning.patch
queue-5.15/ksmbd-return-a-literal-instead-of-err-in-ksmbd_vfs_kern_path_locked.patch
queue-5.15/ksmbd-smbd-change-prototypes-of-rdma-read-write-related-functions.patch
queue-5.15/ksmbd-fix-out-of-bounds-in-init_smb2_rsp_hdr.patch
queue-5.15/ksmbd-fix-possible-memory-leak-in-smb2_lock.patch
queue-5.15/ksmbd-remove-unused-field-in-ksmbd_user-struct.patch
queue-5.15/ksmbd-fix-one-kernel-doc-comment.patch
queue-5.15/ksmbd-no-need-to-wait-for-binded-connection-termination-at-logoff.patch
queue-5.15/ksmbd-fix-race-condition-with-fp.patch
queue-5.15/ksmbd-fix-wrong-signingkey-creation-when-encryption-is-aes256.patch
queue-5.15/ksmbd-update-kconfig-to-note-kerberos-support-and-fix-indentation.patch
queue-5.15/ksmbd-move-setting-smb2_flags_async_command-and-asyncid.patch
queue-5.15/smb3-fix-ksmbd-bigendian-bug-in-oplock-break-and-move-its-struct-to-smbfs_common.patch
queue-5.15/ksmbd-store-fids-as-opaque-u64-integers.patch
queue-5.15/ksmbd-delete-asynchronous-work-from-list.patch
queue-5.15/ksmbd-use-kvzalloc-instead-of-kvmalloc.patch
queue-5.15/ksmbd-smbd-change-the-return-value-of-get_sg_list.patch
queue-5.15/ksmbd-add-missing-compound-request-handing-in-some-commands.patch
queue-5.15/ksmbd-remove-unused-is_char_allowed-function.patch
queue-5.15/ksmbd-use-oid-registry-functions-to-decode-oids.patch
queue-5.15/ksmbd-fix-kernel-doc-comment-of-ksmbd_vfs_kern_path_locked.patch
queue-5.15/ksmbd-use-wait_event-instead-of-schedule_timeout.patch
queue-5.15/ksmbd-check-if-a-mount-point-is-crossed-during-path-lookup.patch
queue-5.15/ksmbd-replace-the-ternary-conditional-operator-with-min.patch




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux