Skip to content

Commit f5ba1cd

Browse files
atheiksmfrench
authored andcommitted
ksmbd: validate share name from share config response
Share config response may contain the share name without casefolding as it is known to the user space daemon. When it is present, casefold and compare it to the share name the share config request was made with. If they differ, we have a share config which is incompatible with the way share config caching is done. This is the case when 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ä <[email protected]> Acked-by: Tom Talpey <[email protected]> Acked-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 141fa98 commit f5ba1cd

File tree

6 files changed

+29
-9
lines changed

6 files changed

+29
-9
lines changed

fs/ksmbd/ksmbd_netlink.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ struct ksmbd_share_config_response {
163163
__u16 force_directory_mode;
164164
__u16 force_uid;
165165
__u16 force_gid;
166-
__u32 reserved[128]; /* Reserved room */
166+
__s8 share_name[KSMBD_REQ_MAX_SHARE_NAME];
167+
__u32 reserved[112]; /* Reserved room */
167168
__u32 veto_list_sz;
168169
__s8 ____payload[];
169170
};

fs/ksmbd/mgmt/share_config.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "user_config.h"
1717
#include "user_session.h"
1818
#include "../transport_ipc.h"
19+
#include "../misc.h"
1920

2021
#define SHARE_HASH_BITS 3
2122
static DEFINE_HASHTABLE(shares_table, SHARE_HASH_BITS);
@@ -119,7 +120,8 @@ static int parse_veto_list(struct ksmbd_share_config *share,
119120
return 0;
120121
}
121122

122-
static struct ksmbd_share_config *share_config_request(const char *name)
123+
static struct ksmbd_share_config *share_config_request(struct unicode_map *um,
124+
const char *name)
123125
{
124126
struct ksmbd_share_config_response *resp;
125127
struct ksmbd_share_config *share = NULL;
@@ -133,6 +135,19 @@ static struct ksmbd_share_config *share_config_request(const char *name)
133135
if (resp->flags == KSMBD_SHARE_FLAG_INVALID)
134136
goto out;
135137

138+
if (*resp->share_name) {
139+
char *cf_resp_name;
140+
bool equal;
141+
142+
cf_resp_name = ksmbd_casefold_sharename(um, resp->share_name);
143+
if (IS_ERR(cf_resp_name))
144+
goto out;
145+
equal = !strcmp(cf_resp_name, name);
146+
kfree(cf_resp_name);
147+
if (!equal)
148+
goto out;
149+
}
150+
136151
share = kzalloc(sizeof(struct ksmbd_share_config), GFP_KERNEL);
137152
if (!share)
138153
goto out;
@@ -190,7 +205,8 @@ static struct ksmbd_share_config *share_config_request(const char *name)
190205
return share;
191206
}
192207

193-
struct ksmbd_share_config *ksmbd_share_config_get(const char *name)
208+
struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um,
209+
const char *name)
194210
{
195211
struct ksmbd_share_config *share;
196212

@@ -202,7 +218,7 @@ struct ksmbd_share_config *ksmbd_share_config_get(const char *name)
202218

203219
if (share)
204220
return share;
205-
return share_config_request(name);
221+
return share_config_request(um, name);
206222
}
207223

208224
bool ksmbd_share_veto_filename(struct ksmbd_share_config *share,

fs/ksmbd/mgmt/share_config.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/workqueue.h>
1010
#include <linux/hashtable.h>
1111
#include <linux/path.h>
12+
#include <linux/unicode.h>
1213

1314
struct ksmbd_share_config {
1415
char *name;
@@ -74,7 +75,8 @@ static inline void ksmbd_share_config_put(struct ksmbd_share_config *share)
7475
__ksmbd_share_config_put(share);
7576
}
7677

77-
struct ksmbd_share_config *ksmbd_share_config_get(const char *name);
78+
struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um,
79+
const char *name);
7880
bool ksmbd_share_veto_filename(struct ksmbd_share_config *share,
7981
const char *filename);
8082
#endif /* __SHARE_CONFIG_MANAGEMENT_H__ */

fs/ksmbd/mgmt/tree_connect.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
2626
struct sockaddr *peer_addr;
2727
int ret;
2828

29-
sc = ksmbd_share_config_get(share_name);
29+
sc = ksmbd_share_config_get(conn->um, share_name);
3030
if (!sc)
3131
return status;
3232

@@ -61,7 +61,7 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
6161
struct ksmbd_share_config *new_sc;
6262

6363
ksmbd_share_config_del(sc);
64-
new_sc = ksmbd_share_config_get(share_name);
64+
new_sc = ksmbd_share_config_get(conn->um, share_name);
6565
if (!new_sc) {
6666
pr_err("Failed to update stale share config\n");
6767
status.ret = -ESTALE;

fs/ksmbd/misc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ void ksmbd_conv_path_to_windows(char *path)
227227
strreplace(path, '/', '\\');
228228
}
229229

230-
static char *casefold_sharename(struct unicode_map *um, const char *name)
230+
char *ksmbd_casefold_sharename(struct unicode_map *um, const char *name)
231231
{
232232
char *cf_name;
233233
int cf_len;
@@ -273,7 +273,7 @@ char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename)
273273
name = (pos + 1);
274274

275275
/* caller has to free the memory */
276-
return casefold_sharename(um, name);
276+
return ksmbd_casefold_sharename(um, name);
277277
}
278278

279279
/**

fs/ksmbd/misc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ int get_nlink(struct kstat *st);
2020
void ksmbd_conv_path_to_unix(char *path);
2121
void ksmbd_strip_last_slash(char *path);
2222
void ksmbd_conv_path_to_windows(char *path);
23+
char *ksmbd_casefold_sharename(struct unicode_map *um, const char *name);
2324
char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename);
2425
char *convert_to_unix_name(struct ksmbd_share_config *share, const char *name);
2526

0 commit comments

Comments
 (0)