From patchwork Wed Sep 28 18:42:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Atte_Heikkil=C3=A4?= X-Patchwork-Id: 12992706 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FB82C32771 for ; Wed, 28 Sep 2022 18:43:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233818AbiI1SnS (ORCPT ); Wed, 28 Sep 2022 14:43:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45772 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232180AbiI1SnR (ORCPT ); Wed, 28 Sep 2022 14:43:17 -0400 Received: from mail-lj1-x22d.google.com (mail-lj1-x22d.google.com [IPv6:2a00:1450:4864:20::22d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B247AB0B0E for ; Wed, 28 Sep 2022 11:43:13 -0700 (PDT) Received: by mail-lj1-x22d.google.com with SMTP id b24so15291507ljk.6 for ; Wed, 28 Sep 2022 11:43:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date; bh=BAPWKeS9iLw1cbT9kIlOTJ68KV+kSS3kPyZx2YMJSiI=; b=mnf708u53MmKJIPeY209tV/cvSwHaQHCqjGEi38fSPkWbeZxEKdCmeWACC9KqPycJN pglS4PIsKuleDzNQDE4npzyhaU5vcwf7+Do/pXydQQVkXvhLIaETmXrcC7H7+jn/4V3j LweCdxuyU3N+h1GD6e5S+/89c0T4hDYdFLSuzsdOz2MUJXaVV4FRQV56aRVP5Qxkv/0f oJcplVOnKCAmR03L3WwO1nFw3bJeFsZgIzIdFMnxzvaMgCKCxrXT7fMJgIdcu+KEIkJ0 ZMC/7YBocDZv9ZQDLyeU8U5lvioyw2WAJ3ZQ8Tnm3MFK0qISGalg+S/QYnnZNCWHlxIh d5dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date; bh=BAPWKeS9iLw1cbT9kIlOTJ68KV+kSS3kPyZx2YMJSiI=; b=OOj6XCNsxxoc7NGe9VgGONX+tQlAhSkhHavwvK6mZm4y4AHeNLn0mrBzYr1SBcfy8m cY9WlyLKIR0czyT+zQY83pFhw8sJSqc8vVrrqXRJqeMHO3BmXxPpYlxNxxoqW4gHiHN6 f5PfV0786FiKFnWOKFLa83p0s53D+MGefAcrEDbdN/9um8uhqkMgEq/mwAp5HuVN5Hsn Ck5eyl1IXBGQa+Z7a6a8lGzCELUHRmyyOhj7LH9eFaWfD9QuaewrAi+2oQgSkH94k/gx NgReHffvMjMp3Ph6ZWgM2OM8YTWdWNQqVdhXRlxkMg5LluxQ1QsPDo1zBv6/jJGpjXXl ZcTA== X-Gm-Message-State: ACrzQf2CbwdSPBKaASEBx9ghWY4pIB9xzjw9LI5/vKvv+Dd4r+PWlFe4 hssANQM4MYfPMcqEb3YYARJ7Ps7dAZ4= X-Google-Smtp-Source: AMsMyM4J4aNvNpyia3J4Fit1NQOuxj/oWMYlUhhxNeVy+vSU6lCvzZ8q/QIqxTNf/2q634LwHMXaBw== X-Received: by 2002:a2e:3909:0:b0:26c:2ea4:1a79 with SMTP id g9-20020a2e3909000000b0026c2ea41a79mr12164053lja.401.1664390591415; Wed, 28 Sep 2022 11:43:11 -0700 (PDT) Received: from pohjola.lan (mobile-user-2e84bd-219.dhcp.inet.fi. [46.132.189.219]) by smtp.gmail.com with ESMTPSA id e30-20020a2e501e000000b00261b175f9c4sm508405ljb.37.2022.09.28.11.43.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Sep 2022 11:43:11 -0700 (PDT) From: =?utf-8?q?Atte_Heikkil=C3=A4?= To: linux-cifs@vger.kernel.org Cc: linkinjeon@kernel.org, =?utf-8?q?Atte_Heikkil=C3=A4?= Subject: [PATCH v2 1/2] ksmbd: validate share name from share config response Date: Wed, 28 Sep 2022 21:42:58 +0300 Message-Id: <20220928184259.75500-1-atteh.mailbox@gmail.com> X-Mailer: git-send-email 2.37.3 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Share config response may contain the share name without casefolding as it is known to the user space daemon. When it is present, compare it to the share name the share config request was made with. If they differ, casefold it and compare again. If they still differ, we have a share config which is incompatible with the way we do share config caching. Currently, this is the case if CONFIG_UNICODE is not set, the share name contains non-ASCII characters, and those non-ASCII characters do not match those in the share name known to user space. In other words, when CONFIG_UNICODE is not set, UTF-8 share names now work but are only case-insensitive in the ASCII range. Signed-off-by: Atte Heikkilä Acked-by: Namjae Jeon --- v2: - no changes were made fs/ksmbd/ksmbd_netlink.h | 3 ++- fs/ksmbd/mgmt/share_config.c | 20 +++++++++++++++++--- fs/ksmbd/mgmt/share_config.h | 4 +++- fs/ksmbd/mgmt/tree_connect.c | 4 ++-- fs/ksmbd/misc.c | 4 ++-- fs/ksmbd/misc.h | 1 + 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/fs/ksmbd/ksmbd_netlink.h b/fs/ksmbd/ksmbd_netlink.h index e0cbcfa98c7e..ff07c67f4565 100644 --- a/fs/ksmbd/ksmbd_netlink.h +++ b/fs/ksmbd/ksmbd_netlink.h @@ -163,7 +163,8 @@ struct ksmbd_share_config_response { __u16 force_directory_mode; __u16 force_uid; __u16 force_gid; - __u32 reserved[128]; /* Reserved room */ + __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; + __u32 reserved[112]; /* Reserved room */ __u32 veto_list_sz; __s8 ____payload[]; }; diff --git a/fs/ksmbd/mgmt/share_config.c b/fs/ksmbd/mgmt/share_config.c index 5d039704c23c..ac766768d283 100644 --- a/fs/ksmbd/mgmt/share_config.c +++ b/fs/ksmbd/mgmt/share_config.c @@ -16,6 +16,7 @@ #include "user_config.h" #include "user_session.h" #include "../transport_ipc.h" +#include "../misc.h" #define SHARE_HASH_BITS 3 static DEFINE_HASHTABLE(shares_table, SHARE_HASH_BITS); @@ -119,7 +120,8 @@ static int parse_veto_list(struct ksmbd_share_config *share, return 0; } -static struct ksmbd_share_config *share_config_request(const char *name) +static struct ksmbd_share_config *share_config_request(struct unicode_map *um, + const char *name) { struct ksmbd_share_config_response *resp; struct ksmbd_share_config *share = NULL; @@ -133,6 +135,17 @@ static struct ksmbd_share_config *share_config_request(const char *name) if (resp->flags == KSMBD_SHARE_FLAG_INVALID) goto out; + if (*resp->share_name && strcmp(resp->share_name, name)) { + char *cf_resp_name; + bool equal; + + cf_resp_name = ksmbd_casefold_sharename(um, resp->share_name); + equal = cf_resp_name && !strcmp(cf_resp_name, name); + kfree(cf_resp_name); + if (!equal) + goto out; + } + share = kzalloc(sizeof(struct ksmbd_share_config), GFP_KERNEL); if (!share) goto out; @@ -190,7 +203,8 @@ static struct ksmbd_share_config *share_config_request(const char *name) return share; } -struct ksmbd_share_config *ksmbd_share_config_get(const char *name) +struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, + const char *name) { struct ksmbd_share_config *share; @@ -202,7 +216,7 @@ struct ksmbd_share_config *ksmbd_share_config_get(const char *name) if (share) return share; - return share_config_request(name); + return share_config_request(um, name); } bool ksmbd_share_veto_filename(struct ksmbd_share_config *share, diff --git a/fs/ksmbd/mgmt/share_config.h b/fs/ksmbd/mgmt/share_config.h index 7f7e89ecfe61..3fd338293942 100644 --- a/fs/ksmbd/mgmt/share_config.h +++ b/fs/ksmbd/mgmt/share_config.h @@ -9,6 +9,7 @@ #include #include #include +#include struct ksmbd_share_config { char *name; @@ -74,7 +75,8 @@ static inline void ksmbd_share_config_put(struct ksmbd_share_config *share) __ksmbd_share_config_put(share); } -struct ksmbd_share_config *ksmbd_share_config_get(const char *name); +struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, + const char *name); bool ksmbd_share_veto_filename(struct ksmbd_share_config *share, const char *filename); #endif /* __SHARE_CONFIG_MANAGEMENT_H__ */ diff --git a/fs/ksmbd/mgmt/tree_connect.c b/fs/ksmbd/mgmt/tree_connect.c index 867c0286b901..8ce17b3fb8da 100644 --- a/fs/ksmbd/mgmt/tree_connect.c +++ b/fs/ksmbd/mgmt/tree_connect.c @@ -26,7 +26,7 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, struct sockaddr *peer_addr; int ret; - sc = ksmbd_share_config_get(share_name); + sc = ksmbd_share_config_get(conn->um, share_name); if (!sc) return status; @@ -61,7 +61,7 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, struct ksmbd_share_config *new_sc; ksmbd_share_config_del(sc); - new_sc = ksmbd_share_config_get(share_name); + new_sc = ksmbd_share_config_get(conn->um, share_name); if (!new_sc) { pr_err("Failed to update stale share config\n"); status.ret = -ESTALE; diff --git a/fs/ksmbd/misc.c b/fs/ksmbd/misc.c index 28459b1efaa8..9e8afaa686e3 100644 --- a/fs/ksmbd/misc.c +++ b/fs/ksmbd/misc.c @@ -227,7 +227,7 @@ void ksmbd_conv_path_to_windows(char *path) strreplace(path, '/', '\\'); } -static char *casefold_sharename(struct unicode_map *um, const char *name) +char *ksmbd_casefold_sharename(struct unicode_map *um, const char *name) { char *cf_name; int cf_len; @@ -273,7 +273,7 @@ char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename) name = (pos + 1); /* caller has to free the memory */ - return casefold_sharename(um, name); + return ksmbd_casefold_sharename(um, name); } /** diff --git a/fs/ksmbd/misc.h b/fs/ksmbd/misc.h index cc72f4e6baf2..1facfcd21200 100644 --- a/fs/ksmbd/misc.h +++ b/fs/ksmbd/misc.h @@ -20,6 +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_casefold_sharename(struct unicode_map *um, const char *name); char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename); char *convert_to_unix_name(struct ksmbd_share_config *share, const char *name); From patchwork Wed Sep 28 18:42:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Atte_Heikkil=C3=A4?= X-Patchwork-Id: 12992705 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2C05EC04A95 for ; Wed, 28 Sep 2022 18:43:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232896AbiI1SnS (ORCPT ); Wed, 28 Sep 2022 14:43:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45774 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233787AbiI1SnR (ORCPT ); Wed, 28 Sep 2022 14:43:17 -0400 Received: from mail-lj1-x22d.google.com (mail-lj1-x22d.google.com [IPv6:2a00:1450:4864:20::22d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70205E21E3 for ; Wed, 28 Sep 2022 11:43:15 -0700 (PDT) Received: by mail-lj1-x22d.google.com with SMTP id a10so15372131ljq.0 for ; Wed, 28 Sep 2022 11:43:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=EYP8vL7OJMTSRvbsRgrt8V/nunoBmz8bZDfD6JnYu0I=; b=Ql0rjh8nR2TskEwraUcN9qxg7wj0uzQ7GCfuDk/bpWEaJDhLLterFmURn9Iyx/GlOU iR+SgJWCPXsX0q7lYZ8S/+JSjJSL0676I6/WzHG03Qq6nr08dh/endyfNZ4Gll32KCNf hJ1Xcpb4N6+NIS/tsb7IpdD21tZGf3Iw/hB1rU1/OELrhQ/kCVEk+9p+4vkhpoifgHYv BB4yOd35ueH4tRQ4RoMnZT3dMBeh9xtcsiN+q6TLlVZCn8fZnbbCji8QVLnuUv6LVn3L s6wlvEcehbSGYE/luoQE7Dkf9cEG7Yfhk3GCQWspyDdlflDHg2aTWmWKZGx3MXm7l8kp nMrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=EYP8vL7OJMTSRvbsRgrt8V/nunoBmz8bZDfD6JnYu0I=; b=ugbb5BBvSeeSx+IaM7nBWzWWJLcwUCjxBNwUKBy0eR+3UkI+11E/i2c0SbwT3PGC6d qeqh0tHlaZrd0Y60jkTqowC0rHch7xi428HI8EHPz8X7uzEXRVS6oqoAT2of/Anakzba YSh4zJNAwUluzCB6i0TMabyRnKQfGEST9N/WKElQHYHGjnLyLi+WRgVqSA+hHnCS3xBY Y5lemkleHFJwhd03vfb9cE7+rJ4ZuEFGmPCrTy18K5qVlgOwdvLqqsF1Eh9/PDyTntYQ lKcTN10Ou/SCl0MTCCFbbCEnYxkjhR3v7n7SpryvxFoYy+CHONlhQgci87C1jWesP3rn bj6w== X-Gm-Message-State: ACrzQf3w6zaWEpNGzKSzCAF4omZdbp5VCV+lW//inieJ486UreB5q8F4 gqQZVzUrXf1AwpGkpqHEh/+5znAff9U= X-Google-Smtp-Source: AMsMyM4hiSsLOrtYYpqWrNcrhX1oMwiA3e1ip4q7Ob5p704P8OtFvwjvCj+Es+0Y994SP/2RK2ok+Q== X-Received: by 2002:a2e:a0d1:0:b0:26c:668a:6b36 with SMTP id f17-20020a2ea0d1000000b0026c668a6b36mr12099196ljm.200.1664390593143; Wed, 28 Sep 2022 11:43:13 -0700 (PDT) Received: from pohjola.lan (mobile-user-2e84bd-219.dhcp.inet.fi. [46.132.189.219]) by smtp.gmail.com with ESMTPSA id e30-20020a2e501e000000b00261b175f9c4sm508405ljb.37.2022.09.28.11.43.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Sep 2022 11:43:12 -0700 (PDT) From: =?utf-8?q?Atte_Heikkil=C3=A4?= To: linux-cifs@vger.kernel.org Cc: linkinjeon@kernel.org, =?utf-8?q?Atte_Heikkil=C3=A4?= Subject: [PATCH v2 2/2] ksmbd-tools: preserve share name case by casefolding at lookup-time Date: Wed, 28 Sep 2022 21:42:59 +0300 Message-Id: <20220928184259.75500-2-atteh.mailbox@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220928184259.75500-1-atteh.mailbox@gmail.com> References: <20220928184259.75500-1-atteh.mailbox@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Preserve the case of share names by doing casefolding at hash table lookup-time. This is preferrable for a few reasons. First, ksmbd can be built such that it is not capable of casefolding UTF-8 share names. Such share names are then case-sensitive if they have non-ASCII characters, and connections to them should succeed only when matching the name in ksmbd.conf, ignoring ASCII case. As such, the case-preserved share name will be sent to ksmbd in the share config response so that ksmbd can casefold it and validate against the share name it knows. This is necessitated by the way share config caching is done. Second, addshare should ideally preserve formatting when modifying ksmbd.conf. Then, preserving the case for user readability reasons is desirable. Also, since ksmbd.conf is just as often edited with a text editor, it is important that share names can be searched using it, which is often not possible when they are written casefolded. Third, case-preserved share names are now used in SRVSVC GET_SHARE_INFO response, with __share_entry_data_ctr0() and __share_entry_data_ctr1(), and so they are seen as written in ksmbd.conf. Also, in shm_casefold_share_name(), note that g_utf8_casefold() aborts on fail, and if g_utf8_normalize() fails, g_ascii_strdown() aborts on fail. `share_name' was leaked in srvsvc_share_get_info_invoke() as the string returned by shm_casefold_share_name() should be freed. Before that, `share_name' was the string returned by g_ascii_strdown() and leaked then as well. Signed-off-by: Atte Heikkilä --- v2: - changed commit message to correctly state that g_utf8_casefold() aborts on fail rather than `cannot fail'. addshare/addshare.c | 6 ++--- addshare/share_admin.c | 8 +++--- include/linux/ksmbd_server.h | 3 ++- include/management/share.h | 3 ++- lib/config_parser.c | 5 ++-- lib/management/share.c | 50 ++++++++++++++++++++++++++---------- mountd/rpc_srvsvc.c | 5 +--- 7 files changed, 53 insertions(+), 27 deletions(-) diff --git a/addshare/addshare.c b/addshare/addshare.c index e91fe5c..80aef55 100644 --- a/addshare/addshare.c +++ b/addshare/addshare.c @@ -124,17 +124,17 @@ int main(int argc, char *argv[]) switch (c) { case 'a': g_free(share); - share = shm_casefold_share_name(optarg, strlen(optarg)); + share = g_strdup(optarg); command = command_add_share; break; case 'd': g_free(share); - share = shm_casefold_share_name(optarg, strlen(optarg)); + share = g_strdup(optarg); command = command_del_share; break; case 'u': g_free(share); - share = shm_casefold_share_name(optarg, strlen(optarg)); + share = g_strdup(optarg); command = command_update_share; break; case 'o': diff --git a/addshare/share_admin.c b/addshare/share_admin.c index c637c61..11b0f14 100644 --- a/addshare/share_admin.c +++ b/addshare/share_admin.c @@ -113,8 +113,8 @@ static void write_remove_share_cb(gpointer key, { struct smbconf_group *g = (struct smbconf_group *)value; - if (!g_ascii_strcasecmp(g->name, name)) { - pr_info("Share `%s' removed\n", g->name); + if (shm_share_name_equal(g->name, name)) { + pr_info("Share `%s' removed\n", name); return; } @@ -187,6 +187,9 @@ int command_update_share(char *smbconf, char *name, char *opts) goto error; } + g_free(existing_group->name); + existing_group->name = g_strdup(name); + g_hash_table_foreach(update_group->kv, update_share_cb, existing_group->kv); @@ -199,7 +202,6 @@ int command_update_share(char *smbconf, char *name, char *opts) close(conf_fd); g_free(aux_name); return 0; - error: g_free(aux_name); return -EINVAL; diff --git a/include/linux/ksmbd_server.h b/include/linux/ksmbd_server.h index 713193d..643e2cd 100644 --- a/include/linux/ksmbd_server.h +++ b/include/linux/ksmbd_server.h @@ -91,7 +91,8 @@ struct ksmbd_share_config_response { __u16 force_directory_mode; __u16 force_uid; __u16 force_gid; - __u32 reserved[128]; /* Reserved room */ + __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; + __u32 reserved[112]; /* Reserved room */ __u32 veto_list_sz; __s8 ____payload[]; }; diff --git a/include/management/share.h b/include/management/share.h index bb3952c..d6ed0a6 100644 --- a/include/management/share.h +++ b/include/management/share.h @@ -141,7 +141,6 @@ static inline int test_share_flag(struct ksmbd_share *share, int flag) struct ksmbd_share *get_ksmbd_share(struct ksmbd_share *share); void put_ksmbd_share(struct ksmbd_share *share); -char *shm_casefold_share_name(char *name, size_t len); struct ksmbd_share *shm_lookup_share(char *name); struct smbconf_group; @@ -150,6 +149,8 @@ int shm_add_new_share(struct smbconf_group *group); void shm_remove_all_shares(void); void shm_destroy(void); +guint shm_share_name_hash(gconstpointer name); +gboolean shm_share_name_equal(gconstpointer lname, gconstpointer rname); int shm_init(void); int shm_lookup_users_map(struct ksmbd_share *share, diff --git a/lib/config_parser.c b/lib/config_parser.c index a1dc85c..53b2e03 100644 --- a/lib/config_parser.c +++ b/lib/config_parser.c @@ -93,7 +93,7 @@ static int add_new_group(char *line) while (*end && *end != ']') end = g_utf8_find_next_char(end, NULL); - name = shm_casefold_share_name(begin + 1, end - begin - 1); + name = g_strndup(begin + 1, end - begin - 1); if (!name) goto out_free; @@ -261,7 +261,8 @@ static int init_smbconf_parser(void) if (parser.groups) return 0; - parser.groups = g_hash_table_new(g_str_hash, g_str_equal); + parser.groups = g_hash_table_new(shm_share_name_hash, + shm_share_name_equal); if (!parser.groups) return -ENOMEM; return 0; diff --git a/lib/management/share.c b/lib/management/share.c index 02e45df..d3d5009 100644 --- a/lib/management/share.c +++ b/lib/management/share.c @@ -227,16 +227,7 @@ void shm_destroy(void) g_rw_lock_clear(&shares_table_lock); } -int shm_init(void) -{ - shares_table = g_hash_table_new(g_str_hash, g_str_equal); - if (!shares_table) - return -ENOMEM; - g_rw_lock_init(&shares_table_lock); - return 0; -} - -char *shm_casefold_share_name(char *name, size_t len) +static char *shm_casefold_share_name(const char *name, size_t len) { char *nfdi_name, *nfdicf_name; @@ -245,9 +236,6 @@ char *shm_casefold_share_name(char *name, size_t len) goto out_ascii; nfdicf_name = g_utf8_casefold(nfdi_name, strlen(nfdi_name)); - if (!nfdicf_name) - goto out_ascii; - g_free(nfdi_name); return nfdicf_name; out_ascii: @@ -255,6 +243,40 @@ out_ascii: return g_ascii_strdown(name, len); } +guint shm_share_name_hash(gconstpointer name) +{ + char *cf_name; + guint hash; + + cf_name = shm_casefold_share_name(name, strlen(name)); + hash = g_str_hash(cf_name); + g_free(cf_name); + return hash; +} + +gboolean shm_share_name_equal(gconstpointer lname, gconstpointer rname) +{ + char *cf_lname, *cf_rname; + gboolean equal; + + cf_lname = shm_casefold_share_name(lname, strlen(lname)); + cf_rname = shm_casefold_share_name(rname, strlen(rname)); + equal = g_str_equal(cf_lname, cf_rname); + g_free(cf_lname); + g_free(cf_rname); + return equal; +} + +int shm_init(void) +{ + shares_table = g_hash_table_new(shm_share_name_hash, + shm_share_name_equal); + if (!shares_table) + return -ENOMEM; + g_rw_lock_init(&shares_table_lock); + return 0; +} + static struct ksmbd_share *__shm_lookup_share(char *name) { return g_hash_table_lookup(shares_table, name); @@ -818,6 +840,8 @@ int shm_handle_share_config_request(struct ksmbd_share *share, resp->force_directory_mode = share->force_directory_mode; resp->force_uid = share->force_uid; resp->force_gid = share->force_gid; + *resp->share_name = 0x00; + strncat(resp->share_name, share->name, KSMBD_REQ_MAX_SHARE_NAME - 1); resp->veto_list_sz = share->veto_list_sz; if (test_share_flag(share, KSMBD_SHARE_FLAG_PIPE)) diff --git a/mountd/rpc_srvsvc.c b/mountd/rpc_srvsvc.c index 8716c34..46c01d9 100644 --- a/mountd/rpc_srvsvc.c +++ b/mountd/rpc_srvsvc.c @@ -169,11 +169,8 @@ static int srvsvc_share_get_info_invoke(struct ksmbd_rpc_pipe *pipe, { struct ksmbd_share *share; int ret; - gchar *share_name; - share_name = shm_casefold_share_name(STR_VAL(hdr->share_name), - strlen(STR_VAL(hdr->share_name))); - share = shm_lookup_share(share_name); + share = shm_lookup_share(STR_VAL(hdr->share_name)); if (!share) return 0;