Skip to content

Commit 22da526

Browse files
committed
Merge tag '5.18-rc3-ksmbd-fixes' of git://git.samba.org/ksmbd
Pull ksmbd server fixes from Steve French: - cap maximum sector size reported to avoid mount problems - reference count fix - fix filename rename race * tag '5.18-rc3-ksmbd-fixes' of git://git.samba.org/ksmbd: ksmbd: set fixed sector size to FS_SECTOR_SIZE_INFORMATION ksmbd: increment reference count of parent fp ksmbd: remove filename in ksmbd_file
2 parents f393592 + 02655a7 commit 22da526

File tree

8 files changed

+52
-66
lines changed

8 files changed

+52
-66
lines changed

fs/ksmbd/misc.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,19 +158,41 @@ 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)
161+
char *convert_to_nt_pathname(struct ksmbd_share_config *share,
162+
struct path *path)
162163
{
163-
char *ab_pathname;
164+
char *pathname, *ab_pathname, *nt_pathname;
165+
int share_path_len = share->path_sz;
164166

165-
if (strlen(filename) == 0)
166-
filename = "\\";
167+
pathname = kmalloc(PATH_MAX, GFP_KERNEL);
168+
if (!pathname)
169+
return ERR_PTR(-EACCES);
167170

168-
ab_pathname = kstrdup(filename, GFP_KERNEL);
169-
if (!ab_pathname)
170-
return NULL;
171+
ab_pathname = d_path(path, pathname, PATH_MAX);
172+
if (IS_ERR(ab_pathname)) {
173+
nt_pathname = ERR_PTR(-EACCES);
174+
goto free_pathname;
175+
}
176+
177+
if (strncmp(ab_pathname, share->path, share_path_len)) {
178+
nt_pathname = ERR_PTR(-EACCES);
179+
goto free_pathname;
180+
}
181+
182+
nt_pathname = kzalloc(strlen(&ab_pathname[share_path_len]) + 2, GFP_KERNEL);
183+
if (!nt_pathname) {
184+
nt_pathname = ERR_PTR(-ENOMEM);
185+
goto free_pathname;
186+
}
187+
if (ab_pathname[share_path_len] == '\0')
188+
strcpy(nt_pathname, "/");
189+
strcat(nt_pathname, &ab_pathname[share_path_len]);
190+
191+
ksmbd_conv_path_to_windows(nt_pathname);
171192

172-
ksmbd_conv_path_to_windows(ab_pathname);
173-
return ab_pathname;
193+
free_pathname:
194+
kfree(pathname);
195+
return nt_pathname;
174196
}
175197

176198
int get_nlink(struct kstat *st)

fs/ksmbd/misc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ 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);
17+
char *convert_to_nt_pathname(struct ksmbd_share_config *share,
18+
struct path *path);
1819
int get_nlink(struct kstat *st);
1920
void ksmbd_conv_path_to_unix(char *path);
2021
void ksmbd_strip_last_slash(char *path);

fs/ksmbd/oplock.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,33 +1694,3 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
16941694
read_unlock(&lease_list_lock);
16951695
return ret_op;
16961696
}
1697-
1698-
int smb2_check_durable_oplock(struct ksmbd_file *fp,
1699-
struct lease_ctx_info *lctx, char *name)
1700-
{
1701-
struct oplock_info *opinfo = opinfo_get(fp);
1702-
int ret = 0;
1703-
1704-
if (opinfo && opinfo->is_lease) {
1705-
if (!lctx) {
1706-
pr_err("open does not include lease\n");
1707-
ret = -EBADF;
1708-
goto out;
1709-
}
1710-
if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key,
1711-
SMB2_LEASE_KEY_SIZE)) {
1712-
pr_err("invalid lease key\n");
1713-
ret = -EBADF;
1714-
goto out;
1715-
}
1716-
if (name && strcmp(fp->filename, name)) {
1717-
pr_err("invalid name reconnect %s\n", name);
1718-
ret = -EINVAL;
1719-
goto out;
1720-
}
1721-
}
1722-
out:
1723-
if (opinfo)
1724-
opinfo_put(opinfo);
1725-
return ret;
1726-
}

fs/ksmbd/oplock.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,4 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
124124
int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
125125
struct lease_ctx_info *lctx);
126126
void destroy_lease_table(struct ksmbd_conn *conn);
127-
int smb2_check_durable_oplock(struct ksmbd_file *fp,
128-
struct lease_ctx_info *lctx, char *name);
129127
#endif /* __KSMBD_OPLOCK_H */

fs/ksmbd/smb2pdu.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/statfs.h>
1212
#include <linux/ethtool.h>
1313
#include <linux/falloc.h>
14+
#include <linux/mount.h>
1415

1516
#include "glob.h"
1617
#include "smbfsctl.h"
@@ -2918,7 +2919,6 @@ int smb2_open(struct ksmbd_work *work)
29182919
goto err_out;
29192920
}
29202921

2921-
fp->filename = name;
29222922
fp->cdoption = req->CreateDisposition;
29232923
fp->daccess = daccess;
29242924
fp->saccess = req->ShareAccess;
@@ -3270,14 +3270,13 @@ int smb2_open(struct ksmbd_work *work)
32703270
if (!rsp->hdr.Status)
32713271
rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
32723272

3273-
if (!fp || !fp->filename)
3274-
kfree(name);
32753273
if (fp)
32763274
ksmbd_fd_put(work, fp);
32773275
smb2_set_err_rsp(work);
32783276
ksmbd_debug(SMB, "Error response: %x\n", rsp->hdr.Status);
32793277
}
32803278

3279+
kfree(name);
32813280
kfree(lc);
32823281

32833282
return 0;
@@ -3895,8 +3894,6 @@ int smb2_query_dir(struct ksmbd_work *work)
38953894
ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr);
38963895
}
38973896

3898-
ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename);
3899-
39003897
if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
39013898
ksmbd_debug(SMB, "Restart directory scan\n");
39023899
generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
@@ -4390,9 +4387,9 @@ static int get_file_all_info(struct ksmbd_work *work,
43904387
return -EACCES;
43914388
}
43924389

4393-
filename = convert_to_nt_pathname(fp->filename);
4394-
if (!filename)
4395-
return -ENOMEM;
4390+
filename = convert_to_nt_pathname(work->tcon->share_conf, &fp->filp->f_path);
4391+
if (IS_ERR(filename))
4392+
return PTR_ERR(filename);
43964393

43974394
inode = file_inode(fp->filp);
43984395
generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat);
@@ -4999,15 +4996,17 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
49994996
case FS_SECTOR_SIZE_INFORMATION:
50004997
{
50014998
struct smb3_fs_ss_info *info;
4999+
unsigned int sector_size =
5000+
min_t(unsigned int, path.mnt->mnt_sb->s_blocksize, 4096);
50025001

50035002
info = (struct smb3_fs_ss_info *)(rsp->Buffer);
50045003

5005-
info->LogicalBytesPerSector = cpu_to_le32(stfs.f_bsize);
5004+
info->LogicalBytesPerSector = cpu_to_le32(sector_size);
50065005
info->PhysicalBytesPerSectorForAtomicity =
5007-
cpu_to_le32(stfs.f_bsize);
5008-
info->PhysicalBytesPerSectorForPerf = cpu_to_le32(stfs.f_bsize);
5006+
cpu_to_le32(sector_size);
5007+
info->PhysicalBytesPerSectorForPerf = cpu_to_le32(sector_size);
50095008
info->FSEffPhysicalBytesPerSectorForAtomicity =
5010-
cpu_to_le32(stfs.f_bsize);
5009+
cpu_to_le32(sector_size);
50115010
info->Flags = cpu_to_le32(SSINFO_FLAGS_ALIGNED_DEVICE |
50125011
SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);
50135012
info->ByteOffsetForSectorAlignment = 0;
@@ -5683,8 +5682,7 @@ static int set_file_allocation_info(struct ksmbd_work *work,
56835682
size = i_size_read(inode);
56845683
rc = ksmbd_vfs_truncate(work, fp, alloc_blks * 512);
56855684
if (rc) {
5686-
pr_err("truncate failed! filename : %s, err %d\n",
5687-
fp->filename, rc);
5685+
pr_err("truncate failed!, err %d\n", rc);
56885686
return rc;
56895687
}
56905688
if (size < alloc_blks * 512)
@@ -5714,12 +5712,10 @@ static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
57145712
* truncated range.
57155713
*/
57165714
if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) {
5717-
ksmbd_debug(SMB, "filename : %s truncated to newsize %lld\n",
5718-
fp->filename, newsize);
5715+
ksmbd_debug(SMB, "truncated to newsize %lld\n", newsize);
57195716
rc = ksmbd_vfs_truncate(work, fp, newsize);
57205717
if (rc) {
5721-
ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n",
5722-
fp->filename, rc);
5718+
ksmbd_debug(SMB, "truncate failed!, err %d\n", rc);
57235719
if (rc != -EAGAIN)
57245720
rc = -EBADF;
57255721
return rc;
@@ -5765,8 +5761,10 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
57655761
if (parent_fp) {
57665762
if (parent_fp->daccess & FILE_DELETE_LE) {
57675763
pr_err("parent dir is opened with delete access\n");
5764+
ksmbd_fd_put(work, parent_fp);
57685765
return -ESHARE;
57695766
}
5767+
ksmbd_fd_put(work, parent_fp);
57705768
}
57715769
next:
57725770
return smb2_rename(work, fp, user_ns, rename_info,

fs/ksmbd/vfs.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
398398

399399
nbytes = kernel_read(filp, rbuf, count, pos);
400400
if (nbytes < 0) {
401-
pr_err("smb read failed for (%s), err = %zd\n",
402-
fp->filename, nbytes);
401+
pr_err("smb read failed, err = %zd\n", nbytes);
403402
return nbytes;
404403
}
405404

@@ -875,8 +874,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work,
875874

876875
err = vfs_truncate(&filp->f_path, size);
877876
if (err)
878-
pr_err("truncate failed for filename : %s err %d\n",
879-
fp->filename, err);
877+
pr_err("truncate failed, err %d\n", err);
880878
return err;
881879
}
882880

fs/ksmbd/vfs_cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,6 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
328328
kfree(smb_lock);
329329
}
330330

331-
kfree(fp->filename);
332331
if (ksmbd_stream_fd(fp))
333332
kfree(fp->stream.name);
334333
kmem_cache_free(filp_cache, fp);
@@ -497,6 +496,7 @@ struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode)
497496
list_for_each_entry(lfp, &ci->m_fp_list, node) {
498497
if (inode == file_inode(lfp->filp)) {
499498
atomic_dec(&ci->m_count);
499+
lfp = ksmbd_fp_get(lfp);
500500
read_unlock(&ci->m_lock);
501501
return lfp;
502502
}

fs/ksmbd/vfs_cache.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ struct ksmbd_inode {
6262

6363
struct ksmbd_file {
6464
struct file *filp;
65-
char *filename;
6665
u64 persistent_id;
6766
u64 volatile_id;
6867

0 commit comments

Comments
 (0)