Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+52 -66
+31 -9
fs/ksmbd/misc.c
··· 158 158 * Return : windows path string or error 159 159 */ 160 160 161 - char *convert_to_nt_pathname(char *filename) 161 + char *convert_to_nt_pathname(struct ksmbd_share_config *share, 162 + struct path *path) 162 163 { 163 - char *ab_pathname; 164 + char *pathname, *ab_pathname, *nt_pathname; 165 + int share_path_len = share->path_sz; 164 166 165 - if (strlen(filename) == 0) 166 - filename = "\\"; 167 + pathname = kmalloc(PATH_MAX, GFP_KERNEL); 168 + if (!pathname) 169 + return ERR_PTR(-EACCES); 167 170 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 + } 171 176 172 - ksmbd_conv_path_to_windows(ab_pathname); 173 - return ab_pathname; 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); 192 + 193 + free_pathname: 194 + kfree(pathname); 195 + return nt_pathname; 174 196 } 175 197 176 198 int get_nlink(struct kstat *st)
+2 -1
fs/ksmbd/misc.h
··· 14 14 int match_pattern(const char *str, size_t len, const char *pattern); 15 15 int ksmbd_validate_filename(char *filename); 16 16 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); 18 19 int get_nlink(struct kstat *st); 19 20 void ksmbd_conv_path_to_unix(char *path); 20 21 void ksmbd_strip_last_slash(char *path);
-30
fs/ksmbd/oplock.c
··· 1694 1694 read_unlock(&lease_list_lock); 1695 1695 return ret_op; 1696 1696 } 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 - }
-2
fs/ksmbd/oplock.h
··· 124 124 int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci, 125 125 struct lease_ctx_info *lctx); 126 126 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); 129 127 #endif /* __KSMBD_OPLOCK_H */
+16 -18
fs/ksmbd/smb2pdu.c
··· 11 11 #include <linux/statfs.h> 12 12 #include <linux/ethtool.h> 13 13 #include <linux/falloc.h> 14 + #include <linux/mount.h> 14 15 15 16 #include "glob.h" 16 17 #include "smbfsctl.h" ··· 2919 2918 goto err_out; 2920 2919 } 2921 2920 2922 - fp->filename = name; 2923 2921 fp->cdoption = req->CreateDisposition; 2924 2922 fp->daccess = daccess; 2925 2923 fp->saccess = req->ShareAccess; ··· 3270 3270 if (!rsp->hdr.Status) 3271 3271 rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR; 3272 3272 3273 - if (!fp || !fp->filename) 3274 - kfree(name); 3275 3273 if (fp) 3276 3274 ksmbd_fd_put(work, fp); 3277 3275 smb2_set_err_rsp(work); 3278 3276 ksmbd_debug(SMB, "Error response: %x\n", rsp->hdr.Status); 3279 3277 } 3280 3278 3279 + kfree(name); 3281 3280 kfree(lc); 3282 3281 3283 3282 return 0; ··· 3894 3895 ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr); 3895 3896 } 3896 3897 3897 - ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename); 3898 - 3899 3898 if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) { 3900 3899 ksmbd_debug(SMB, "Restart directory scan\n"); 3901 3900 generic_file_llseek(dir_fp->filp, 0, SEEK_SET); ··· 4387 4390 return -EACCES; 4388 4391 } 4389 4392 4390 - filename = convert_to_nt_pathname(fp->filename); 4391 - if (!filename) 4392 - return -ENOMEM; 4393 + filename = convert_to_nt_pathname(work->tcon->share_conf, &fp->filp->f_path); 4394 + if (IS_ERR(filename)) 4395 + return PTR_ERR(filename); 4393 4396 4394 4397 inode = file_inode(fp->filp); 4395 4398 generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat); ··· 4996 4999 case FS_SECTOR_SIZE_INFORMATION: 4997 5000 { 4998 5001 struct smb3_fs_ss_info *info; 5002 + unsigned int sector_size = 5003 + min_t(unsigned int, path.mnt->mnt_sb->s_blocksize, 4096); 4999 5004 5000 5005 info = (struct smb3_fs_ss_info *)(rsp->Buffer); 5001 5006 5002 - info->LogicalBytesPerSector = cpu_to_le32(stfs.f_bsize); 5007 + info->LogicalBytesPerSector = cpu_to_le32(sector_size); 5003 5008 info->PhysicalBytesPerSectorForAtomicity = 5004 - cpu_to_le32(stfs.f_bsize); 5005 - info->PhysicalBytesPerSectorForPerf = cpu_to_le32(stfs.f_bsize); 5009 + cpu_to_le32(sector_size); 5010 + info->PhysicalBytesPerSectorForPerf = cpu_to_le32(sector_size); 5006 5011 info->FSEffPhysicalBytesPerSectorForAtomicity = 5007 - cpu_to_le32(stfs.f_bsize); 5012 + cpu_to_le32(sector_size); 5008 5013 info->Flags = cpu_to_le32(SSINFO_FLAGS_ALIGNED_DEVICE | 5009 5014 SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE); 5010 5015 info->ByteOffsetForSectorAlignment = 0; ··· 5682 5683 size = i_size_read(inode); 5683 5684 rc = ksmbd_vfs_truncate(work, fp, alloc_blks * 512); 5684 5685 if (rc) { 5685 - pr_err("truncate failed! filename : %s, err %d\n", 5686 - fp->filename, rc); 5686 + pr_err("truncate failed!, err %d\n", rc); 5687 5687 return rc; 5688 5688 } 5689 5689 if (size < alloc_blks * 512) ··· 5712 5714 * truncated range. 5713 5715 */ 5714 5716 if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) { 5715 - ksmbd_debug(SMB, "filename : %s truncated to newsize %lld\n", 5716 - fp->filename, newsize); 5717 + ksmbd_debug(SMB, "truncated to newsize %lld\n", newsize); 5717 5718 rc = ksmbd_vfs_truncate(work, fp, newsize); 5718 5719 if (rc) { 5719 - ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n", 5720 - fp->filename, rc); 5720 + ksmbd_debug(SMB, "truncate failed!, err %d\n", rc); 5721 5721 if (rc != -EAGAIN) 5722 5722 rc = -EBADF; 5723 5723 return rc; ··· 5761 5765 if (parent_fp) { 5762 5766 if (parent_fp->daccess & FILE_DELETE_LE) { 5763 5767 pr_err("parent dir is opened with delete access\n"); 5768 + ksmbd_fd_put(work, parent_fp); 5764 5769 return -ESHARE; 5765 5770 } 5771 + ksmbd_fd_put(work, parent_fp); 5766 5772 } 5767 5773 next: 5768 5774 return smb2_rename(work, fp, user_ns, rename_info,
+2 -4
fs/ksmbd/vfs.c
··· 398 398 399 399 nbytes = kernel_read(filp, rbuf, count, pos); 400 400 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); 403 402 return nbytes; 404 403 } 405 404 ··· 874 875 875 876 err = vfs_truncate(&filp->f_path, size); 876 877 if (err) 877 - pr_err("truncate failed for filename : %s err %d\n", 878 - fp->filename, err); 878 + pr_err("truncate failed, err %d\n", err); 879 879 return err; 880 880 } 881 881
+1 -1
fs/ksmbd/vfs_cache.c
··· 328 328 kfree(smb_lock); 329 329 } 330 330 331 - kfree(fp->filename); 332 331 if (ksmbd_stream_fd(fp)) 333 332 kfree(fp->stream.name); 334 333 kmem_cache_free(filp_cache, fp); ··· 496 497 list_for_each_entry(lfp, &ci->m_fp_list, node) { 497 498 if (inode == file_inode(lfp->filp)) { 498 499 atomic_dec(&ci->m_count); 500 + lfp = ksmbd_fp_get(lfp); 499 501 read_unlock(&ci->m_lock); 500 502 return lfp; 501 503 }
-1
fs/ksmbd/vfs_cache.h
··· 62 62 63 63 struct ksmbd_file { 64 64 struct file *filp; 65 - char *filename; 66 65 u64 persistent_id; 67 66 u64 volatile_id; 68 67