Skip to content

Commit 5e5d759

Browse files
committed
Merge tag '5.15-rc2-ksmbd-fixes' of git://git.samba.org/ksmbd
Pull ksmbd fixes from Steve French: "Five fixes for the ksmbd kernel server, including three security fixes: - remove follow symlinks support - use LOOKUP_BENEATH to prevent out of share access - SMB3 compounding security fix - fix for returning the default streams correctly, fixing a bug when writing ppt or doc files from some clients - logging more clearly that ksmbd is experimental (at module load time)" * tag '5.15-rc2-ksmbd-fixes' of git://git.samba.org/ksmbd: ksmbd: use LOOKUP_BENEATH to prevent the out of share access ksmbd: remove follow symlinks support ksmbd: check protocol id in ksmbd_verify_smb_message() ksmbd: add default data stream name in FILE_STREAM_INFORMATION ksmbd: log that server is experimental at module load
2 parents 996148e + 265fd19 commit 5e5d759

File tree

8 files changed

+164
-260
lines changed

8 files changed

+164
-260
lines changed

fs/ksmbd/misc.c

Lines changed: 19 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -158,25 +158,21 @@ int parse_stream_name(char *filename, char **stream_name, int *s_type)
158158
* Return : windows path string or error
159159
*/
160160

161-
char *convert_to_nt_pathname(char *filename, char *sharepath)
161+
char *convert_to_nt_pathname(char *filename)
162162
{
163163
char *ab_pathname;
164-
int len, name_len;
165164

166-
name_len = strlen(filename);
167-
ab_pathname = kmalloc(name_len, GFP_KERNEL);
168-
if (!ab_pathname)
169-
return NULL;
170-
171-
ab_pathname[0] = '\\';
172-
ab_pathname[1] = '\0';
165+
if (strlen(filename) == 0) {
166+
ab_pathname = kmalloc(2, GFP_KERNEL);
167+
ab_pathname[0] = '\\';
168+
ab_pathname[1] = '\0';
169+
} else {
170+
ab_pathname = kstrdup(filename, GFP_KERNEL);
171+
if (!ab_pathname)
172+
return NULL;
173173

174-
len = strlen(sharepath);
175-
if (!strncmp(filename, sharepath, len) && name_len != len) {
176-
strscpy(ab_pathname, &filename[len], name_len);
177174
ksmbd_conv_path_to_windows(ab_pathname);
178175
}
179-
180176
return ab_pathname;
181177
}
182178

@@ -191,77 +187,19 @@ int get_nlink(struct kstat *st)
191187
return nlink;
192188
}
193189

194-
char *ksmbd_conv_path_to_unix(char *path)
190+
void ksmbd_conv_path_to_unix(char *path)
195191
{
196-
size_t path_len, remain_path_len, out_path_len;
197-
char *out_path, *out_next;
198-
int i, pre_dotdot_cnt = 0, slash_cnt = 0;
199-
bool is_last;
200-
201192
strreplace(path, '\\', '/');
202-
path_len = strlen(path);
203-
remain_path_len = path_len;
204-
if (path_len == 0)
205-
return ERR_PTR(-EINVAL);
206-
207-
out_path = kzalloc(path_len + 2, GFP_KERNEL);
208-
if (!out_path)
209-
return ERR_PTR(-ENOMEM);
210-
out_path_len = 0;
211-
out_next = out_path;
212-
213-
do {
214-
char *name = path + path_len - remain_path_len;
215-
char *next = strchrnul(name, '/');
216-
size_t name_len = next - name;
217-
218-
is_last = !next[0];
219-
if (name_len == 2 && name[0] == '.' && name[1] == '.') {
220-
pre_dotdot_cnt++;
221-
/* handle the case that path ends with "/.." */
222-
if (is_last)
223-
goto follow_dotdot;
224-
} else {
225-
if (pre_dotdot_cnt) {
226-
follow_dotdot:
227-
slash_cnt = 0;
228-
for (i = out_path_len - 1; i >= 0; i--) {
229-
if (out_path[i] == '/' &&
230-
++slash_cnt == pre_dotdot_cnt + 1)
231-
break;
232-
}
233-
234-
if (i < 0 &&
235-
slash_cnt != pre_dotdot_cnt) {
236-
kfree(out_path);
237-
return ERR_PTR(-EINVAL);
238-
}
239-
240-
out_next = &out_path[i+1];
241-
*out_next = '\0';
242-
out_path_len = i + 1;
243-
244-
}
245-
246-
if (name_len != 0 &&
247-
!(name_len == 1 && name[0] == '.') &&
248-
!(name_len == 2 && name[0] == '.' && name[1] == '.')) {
249-
next[0] = '\0';
250-
sprintf(out_next, "%s/", name);
251-
out_next += name_len + 1;
252-
out_path_len += name_len + 1;
253-
next[0] = '/';
254-
}
255-
pre_dotdot_cnt = 0;
256-
}
193+
}
257194

258-
remain_path_len -= name_len + 1;
259-
} while (!is_last);
195+
void ksmbd_strip_last_slash(char *path)
196+
{
197+
int len = strlen(path);
260198

261-
if (out_path_len > 0)
262-
out_path[out_path_len-1] = '\0';
263-
path[path_len] = '\0';
264-
return out_path;
199+
while (len && path[len - 1] == '/') {
200+
path[len - 1] = '\0';
201+
len--;
202+
}
265203
}
266204

267205
void ksmbd_conv_path_to_windows(char *path)
@@ -298,7 +236,7 @@ char *ksmbd_extract_sharename(char *treename)
298236
*
299237
* Return: converted name on success, otherwise NULL
300238
*/
301-
char *convert_to_unix_name(struct ksmbd_share_config *share, char *name)
239+
char *convert_to_unix_name(struct ksmbd_share_config *share, const char *name)
302240
{
303241
int no_slash = 0, name_len, path_len;
304242
char *new_name;

fs/ksmbd/misc.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ struct ksmbd_file;
1414
int match_pattern(const char *str, size_t len, const char *pattern);
1515
int ksmbd_validate_filename(char *filename);
1616
int parse_stream_name(char *filename, char **stream_name, int *s_type);
17-
char *convert_to_nt_pathname(char *filename, char *sharepath);
17+
char *convert_to_nt_pathname(char *filename);
1818
int get_nlink(struct kstat *st);
19-
char *ksmbd_conv_path_to_unix(char *path);
19+
void ksmbd_conv_path_to_unix(char *path);
20+
void ksmbd_strip_last_slash(char *path);
2021
void ksmbd_conv_path_to_windows(char *path);
2122
char *ksmbd_extract_sharename(char *treename);
22-
char *convert_to_unix_name(struct ksmbd_share_config *share, char *name);
23+
char *convert_to_unix_name(struct ksmbd_share_config *share, const char *name);
2324

2425
#define KSMBD_DIR_INFO_ALIGNMENT 8
2526
struct ksmbd_dir_info;

fs/ksmbd/server.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,9 @@ static int __init ksmbd_server_init(void)
584584
ret = ksmbd_workqueue_init();
585585
if (ret)
586586
goto err_crypto_destroy;
587+
588+
pr_warn_once("The ksmbd server is experimental, use at your own risk.\n");
589+
587590
return 0;
588591

589592
err_crypto_destroy:

0 commit comments

Comments
 (0)