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 '6.1-rc-ksmbd-fixes' of git://git.samba.org/ksmbd

Pull ksmbd updates from Steve French:

- RDMA (smbdirect) fixes

- fixes for SMB3.1.1 POSIX Extensions (especially for id mapping)

- various casemapping fixes for mount and lookup

- UID mapping fixes

- fix confusing error message

- protocol negotiation fixes, including NTLMSSP fix

- two encryption fixes

- directory listing fix

- some cleanup fixes

* tag '6.1-rc-ksmbd-fixes' of git://git.samba.org/ksmbd: (24 commits)
ksmbd: validate share name from share config response
ksmbd: call ib_drain_qp when disconnected
ksmbd: make utf-8 file name comparison work in __caseless_lookup()
ksmbd: Fix user namespace mapping
ksmbd: hide socket error message when ipv6 config is disable
ksmbd: reduce server smbdirect max send/receive segment sizes
ksmbd: decrease the number of SMB3 smbdirect server SGEs
ksmbd: Fix wrong return value and message length check in smb2_ioctl()
ksmbd: set NTLMSSP_NEGOTIATE_SEAL flag to challenge blob
ksmbd: fix encryption failure issue for session logoff response
ksmbd: fix endless loop when encryption for response fails
ksmbd: fill sids in SMB_FIND_FILE_POSIX_INFO response
ksmbd: set file permission mode to match Samba server posix extension behavior
ksmbd: change security id to the one samba used for posix extension
ksmbd: update documentation
ksmbd: casefold utf-8 share names and fix ascii lowercase conversion
ksmbd: port to vfs{g,u}id_t and associated helpers
ksmbd: fix incorrect handling of iterate_dir
MAINTAINERS: remove Hyunchul Lee from ksmbd maintainers
MAINTAINERS: Add Tom Talpey as ksmbd reviewer
...

+284 -152
+30 -12
Documentation/filesystems/cifs/ksmbd.rst
··· 118 118 How to run 119 119 ========== 120 120 121 - 1. Download ksmbd-tools and compile them. 122 - - https://github.com/cifsd-team/ksmbd-tools 121 + 1. Download ksmbd-tools(https://github.com/cifsd-team/ksmbd-tools/releases) and 122 + compile them. 123 123 124 - 2. Create user/password for SMB share. 124 + - Refer README(https://github.com/cifsd-team/ksmbd-tools/blob/master/README.md) 125 + to know how to use ksmbd.mountd/adduser/addshare/control utils 125 126 126 - # mkdir /etc/ksmbd/ 127 - # ksmbd.adduser -a <Enter USERNAME for SMB share access> 127 + $ ./autogen.sh 128 + $ ./configure --with-rundir=/run 129 + $ make && sudo make install 128 130 129 - 3. Create /etc/ksmbd/smb.conf file, add SMB share in smb.conf file 130 - - Refer smb.conf.example and 131 - https://github.com/cifsd-team/ksmbd-tools/blob/master/Documentation/configuration.txt 131 + 2. Create /usr/local/etc/ksmbd/ksmbd.conf file, add SMB share in ksmbd.conf file. 132 132 133 - 4. Insert ksmbd.ko module 133 + - Refer ksmbd.conf.example in ksmbd-utils, See ksmbd.conf manpage 134 + for details to configure shares. 134 135 135 - # insmod ksmbd.ko 136 + $ man ksmbd.conf 137 + 138 + 3. Create user/password for SMB share. 139 + 140 + - See ksmbd.adduser manpage. 141 + 142 + $ man ksmbd.adduser 143 + $ sudo ksmbd.adduser -a <Enter USERNAME for SMB share access> 144 + 145 + 4. Insert ksmbd.ko module after build your kernel. No need to load module 146 + if ksmbd is built into the kernel. 147 + 148 + - Set ksmbd in menuconfig(e.g. $ make menuconfig) 149 + [*] Network File Systems ---> 150 + <M> SMB3 server support (EXPERIMENTAL) 151 + 152 + $ sudo modprobe ksmbd.ko 136 153 137 154 5. Start ksmbd user space daemon 138 - # ksmbd.mountd 139 155 140 - 6. Access share from Windows or Linux using CIFS 156 + $ sudo ksmbd.mountd 157 + 158 + 6. Access share from Windows or Linux using SMB3 client (cifs.ko or smbclient of samba) 141 159 142 160 Shutdown KSMBD 143 161 ==============
+1 -1
MAINTAINERS
··· 11101 11101 KERNEL SMB3 SERVER (KSMBD) 11102 11102 M: Namjae Jeon <linkinjeon@kernel.org> 11103 11103 M: Steve French <sfrench@samba.org> 11104 - M: Hyunchul Lee <hyc.lee@gmail.com> 11105 11104 R: Sergey Senozhatsky <senozhatsky@chromium.org> 11105 + R: Tom Talpey <tom@talpey.com> 11106 11106 L: linux-cifs@vger.kernel.org 11107 11107 S: Maintained 11108 11108 T: git git://git.samba.org/ksmbd.git
+11 -4
fs/ksmbd/auth.c
··· 424 424 NTLMSSP_NEGOTIATE_56); 425 425 } 426 426 427 + if (cflags & NTLMSSP_NEGOTIATE_SEAL && smb3_encryption_negotiated(conn)) 428 + flags |= NTLMSSP_NEGOTIATE_SEAL; 429 + 427 430 if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) 428 431 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 429 432 ··· 987 984 return rc; 988 985 } 989 986 990 - static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id, 987 + static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id, 991 988 int enc, u8 *key) 992 989 { 993 990 struct ksmbd_session *sess; 994 991 u8 *ses_enc_key; 995 992 996 - sess = ksmbd_session_lookup_all(conn, ses_id); 993 + if (enc) 994 + sess = work->sess; 995 + else 996 + sess = ksmbd_session_lookup_all(work->conn, ses_id); 997 997 if (!sess) 998 998 return -EINVAL; 999 999 ··· 1084 1078 return sg; 1085 1079 } 1086 1080 1087 - int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, 1081 + int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov, 1088 1082 unsigned int nvec, int enc) 1089 1083 { 1084 + struct ksmbd_conn *conn = work->conn; 1090 1085 struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base); 1091 1086 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20; 1092 1087 int rc; ··· 1101 1094 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize); 1102 1095 struct ksmbd_crypto_ctx *ctx; 1103 1096 1104 - rc = ksmbd_get_encryption_key(conn, 1097 + rc = ksmbd_get_encryption_key(work, 1105 1098 le64_to_cpu(tr_hdr->SessionId), 1106 1099 enc, 1107 1100 key);
+2 -1
fs/ksmbd/auth.h
··· 33 33 34 34 struct ksmbd_session; 35 35 struct ksmbd_conn; 36 + struct ksmbd_work; 36 37 struct kvec; 37 38 38 - int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, 39 + int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov, 39 40 unsigned int nvec, int enc); 40 41 void ksmbd_copy_gss_neg_header(void *buf); 41 42 int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
+8
fs/ksmbd/connection.c
··· 60 60 conn->local_nls = load_nls("utf8"); 61 61 if (!conn->local_nls) 62 62 conn->local_nls = load_nls_default(); 63 + if (IS_ENABLED(CONFIG_UNICODE)) 64 + conn->um = utf8_load(UNICODE_AGE(12, 1, 0)); 65 + else 66 + conn->um = ERR_PTR(-EOPNOTSUPP); 67 + if (IS_ERR(conn->um)) 68 + conn->um = NULL; 63 69 atomic_set(&conn->req_running, 0); 64 70 atomic_set(&conn->r_count, 0); 65 71 conn->total_credits = 1; ··· 356 350 wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0); 357 351 358 352 353 + if (IS_ENABLED(CONFIG_UNICODE)) 354 + utf8_unload(conn->um); 359 355 unload_nls(conn->local_nls); 360 356 if (default_conn_ops.terminate_fn) 361 357 default_conn_ops.terminate_fn(conn);
+2
fs/ksmbd/connection.h
··· 14 14 #include <net/request_sock.h> 15 15 #include <linux/kthread.h> 16 16 #include <linux/nls.h> 17 + #include <linux/unicode.h> 17 18 18 19 #include "smb_common.h" 19 20 #include "ksmbd_work.h" ··· 47 46 char *request_buf; 48 47 struct ksmbd_transport *transport; 49 48 struct nls_table *local_nls; 49 + struct unicode_map *um; 50 50 struct list_head conns_list; 51 51 /* smb session 1 per user */ 52 52 struct xarray sessions;
+2 -1
fs/ksmbd/ksmbd_netlink.h
··· 163 163 __u16 force_directory_mode; 164 164 __u16 force_uid; 165 165 __u16 force_gid; 166 - __u32 reserved[128]; /* Reserved room */ 166 + __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; 167 + __u32 reserved[112]; /* Reserved room */ 167 168 __u32 veto_list_sz; 168 169 __s8 ____payload[]; 169 170 };
+21 -15
fs/ksmbd/mgmt/share_config.c
··· 16 16 #include "user_config.h" 17 17 #include "user_session.h" 18 18 #include "../transport_ipc.h" 19 + #include "../misc.h" 19 20 20 21 #define SHARE_HASH_BITS 3 21 22 static DEFINE_HASHTABLE(shares_table, SHARE_HASH_BITS); ··· 27 26 struct list_head list; 28 27 }; 29 28 30 - static unsigned int share_name_hash(char *name) 29 + static unsigned int share_name_hash(const char *name) 31 30 { 32 31 return jhash(name, strlen(name), 0); 33 32 } ··· 73 72 return share; 74 73 } 75 74 76 - static struct ksmbd_share_config *__share_lookup(char *name) 75 + static struct ksmbd_share_config *__share_lookup(const char *name) 77 76 { 78 77 struct ksmbd_share_config *share; 79 78 unsigned int key = share_name_hash(name); ··· 120 119 return 0; 121 120 } 122 121 123 - static struct ksmbd_share_config *share_config_request(char *name) 122 + static struct ksmbd_share_config *share_config_request(struct unicode_map *um, 123 + const char *name) 124 124 { 125 125 struct ksmbd_share_config_response *resp; 126 126 struct ksmbd_share_config *share = NULL; ··· 134 132 135 133 if (resp->flags == KSMBD_SHARE_FLAG_INVALID) 136 134 goto out; 135 + 136 + if (*resp->share_name) { 137 + char *cf_resp_name; 138 + bool equal; 139 + 140 + cf_resp_name = ksmbd_casefold_sharename(um, resp->share_name); 141 + if (IS_ERR(cf_resp_name)) 142 + goto out; 143 + equal = !strcmp(cf_resp_name, name); 144 + kfree(cf_resp_name); 145 + if (!equal) 146 + goto out; 147 + } 137 148 138 149 share = kzalloc(sizeof(struct ksmbd_share_config), GFP_KERNEL); 139 150 if (!share) ··· 205 190 return share; 206 191 } 207 192 208 - static void strtolower(char *share_name) 209 - { 210 - while (*share_name) { 211 - *share_name = tolower(*share_name); 212 - share_name++; 213 - } 214 - } 215 - 216 - struct ksmbd_share_config *ksmbd_share_config_get(char *name) 193 + struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, 194 + const char *name) 217 195 { 218 196 struct ksmbd_share_config *share; 219 - 220 - strtolower(name); 221 197 222 198 down_read(&shares_table_lock); 223 199 share = __share_lookup(name); ··· 218 212 219 213 if (share) 220 214 return share; 221 - return share_config_request(name); 215 + return share_config_request(um, name); 222 216 } 223 217 224 218 bool ksmbd_share_veto_filename(struct ksmbd_share_config *share,
+3 -1
fs/ksmbd/mgmt/share_config.h
··· 9 9 #include <linux/workqueue.h> 10 10 #include <linux/hashtable.h> 11 11 #include <linux/path.h> 12 + #include <linux/unicode.h> 12 13 13 14 struct ksmbd_share_config { 14 15 char *name; ··· 75 74 __ksmbd_share_config_put(share); 76 75 } 77 76 78 - struct ksmbd_share_config *ksmbd_share_config_get(char *name); 77 + struct ksmbd_share_config *ksmbd_share_config_get(struct unicode_map *um, 78 + const char *name); 79 79 bool ksmbd_share_veto_filename(struct ksmbd_share_config *share, 80 80 const char *filename); 81 81 #endif /* __SHARE_CONFIG_MANAGEMENT_H__ */
+3 -3
fs/ksmbd/mgmt/tree_connect.c
··· 17 17 18 18 struct ksmbd_tree_conn_status 19 19 ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, 20 - char *share_name) 20 + const char *share_name) 21 21 { 22 22 struct ksmbd_tree_conn_status status = {-ENOENT, NULL}; 23 23 struct ksmbd_tree_connect_response *resp = NULL; ··· 26 26 struct sockaddr *peer_addr; 27 27 int ret; 28 28 29 - sc = ksmbd_share_config_get(share_name); 29 + sc = ksmbd_share_config_get(conn->um, share_name); 30 30 if (!sc) 31 31 return status; 32 32 ··· 61 61 struct ksmbd_share_config *new_sc; 62 62 63 63 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); 65 65 if (!new_sc) { 66 66 pr_err("Failed to update stale share config\n"); 67 67 status.ret = -ESTALE;
+1 -1
fs/ksmbd/mgmt/tree_connect.h
··· 42 42 43 43 struct ksmbd_tree_conn_status 44 44 ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, 45 - char *share_name); 45 + const char *share_name); 46 46 47 47 int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, 48 48 struct ksmbd_tree_connect *tree_conn);
+37 -9
fs/ksmbd/misc.c
··· 7 7 #include <linux/kernel.h> 8 8 #include <linux/xattr.h> 9 9 #include <linux/fs.h> 10 + #include <linux/unicode.h> 10 11 11 12 #include "misc.h" 12 13 #include "smb_common.h" ··· 160 159 */ 161 160 162 161 char *convert_to_nt_pathname(struct ksmbd_share_config *share, 163 - struct path *path) 162 + const struct path *path) 164 163 { 165 164 char *pathname, *ab_pathname, *nt_pathname; 166 165 int share_path_len = share->path_sz; ··· 227 226 strreplace(path, '/', '\\'); 228 227 } 229 228 229 + char *ksmbd_casefold_sharename(struct unicode_map *um, const char *name) 230 + { 231 + char *cf_name; 232 + int cf_len; 233 + 234 + cf_name = kzalloc(KSMBD_REQ_MAX_SHARE_NAME, GFP_KERNEL); 235 + if (!cf_name) 236 + return ERR_PTR(-ENOMEM); 237 + 238 + if (IS_ENABLED(CONFIG_UNICODE) && um) { 239 + const struct qstr q_name = {.name = name, .len = strlen(name)}; 240 + 241 + cf_len = utf8_casefold(um, &q_name, cf_name, 242 + KSMBD_REQ_MAX_SHARE_NAME); 243 + if (cf_len < 0) 244 + goto out_ascii; 245 + 246 + return cf_name; 247 + } 248 + 249 + out_ascii: 250 + cf_len = strscpy(cf_name, name, KSMBD_REQ_MAX_SHARE_NAME); 251 + if (cf_len < 0) { 252 + kfree(cf_name); 253 + return ERR_PTR(-E2BIG); 254 + } 255 + 256 + for (; *cf_name; ++cf_name) 257 + *cf_name = isascii(*cf_name) ? tolower(*cf_name) : *cf_name; 258 + return cf_name - cf_len; 259 + } 260 + 230 261 /** 231 262 * ksmbd_extract_sharename() - get share name from tree connect request 232 263 * @treename: buffer containing tree name and share name 233 264 * 234 265 * Return: share name on success, otherwise error 235 266 */ 236 - char *ksmbd_extract_sharename(char *treename) 267 + char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename) 237 268 { 238 - char *name = treename; 239 - char *dst; 240 - char *pos = strrchr(name, '\\'); 269 + const char *name = treename, *pos = strrchr(name, '\\'); 241 270 242 271 if (pos) 243 272 name = (pos + 1); 244 273 245 274 /* caller has to free the memory */ 246 - dst = kstrdup(name, GFP_KERNEL); 247 - if (!dst) 248 - return ERR_PTR(-ENOMEM); 249 - return dst; 275 + return ksmbd_casefold_sharename(um, name); 250 276 } 251 277 252 278 /**
+3 -2
fs/ksmbd/misc.h
··· 15 15 int ksmbd_validate_filename(char *filename); 16 16 int parse_stream_name(char *filename, char **stream_name, int *s_type); 17 17 char *convert_to_nt_pathname(struct ksmbd_share_config *share, 18 - struct path *path); 18 + const struct path *path); 19 19 int get_nlink(struct kstat *st); 20 20 void ksmbd_conv_path_to_unix(char *path); 21 21 void ksmbd_strip_last_slash(char *path); 22 22 void ksmbd_conv_path_to_windows(char *path); 23 - char *ksmbd_extract_sharename(char *treename); 23 + char *ksmbd_casefold_sharename(struct unicode_map *um, const char *name); 24 + char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename); 24 25 char *convert_to_unix_name(struct ksmbd_share_config *share, const char *name); 25 26 26 27 #define KSMBD_DIR_INFO_ALIGNMENT 8
+6 -2
fs/ksmbd/ndr.c
··· 345 345 { 346 346 unsigned int ref_id = 0x00020000; 347 347 int ret; 348 + vfsuid_t vfsuid; 349 + vfsgid_t vfsgid; 348 350 349 351 n->offset = 0; 350 352 n->length = 1024; ··· 374 372 if (ret) 375 373 return ret; 376 374 377 - ret = ndr_write_int64(n, from_kuid(&init_user_ns, i_uid_into_mnt(user_ns, inode))); 375 + vfsuid = i_uid_into_vfsuid(user_ns, inode); 376 + ret = ndr_write_int64(n, from_kuid(&init_user_ns, vfsuid_into_kuid(vfsuid))); 378 377 if (ret) 379 378 return ret; 380 - ret = ndr_write_int64(n, from_kgid(&init_user_ns, i_gid_into_mnt(user_ns, inode))); 379 + vfsgid = i_gid_into_vfsgid(user_ns, inode); 380 + ret = ndr_write_int64(n, from_kgid(&init_user_ns, vfsgid_into_kgid(vfsgid))); 381 381 if (ret) 382 382 return ret; 383 383 ret = ndr_write_int32(n, inode->i_mode);
+19 -8
fs/ksmbd/oplock.c
··· 1609 1609 struct create_posix_rsp *buf; 1610 1610 struct inode *inode = file_inode(fp->filp); 1611 1611 struct user_namespace *user_ns = file_mnt_user_ns(fp->filp); 1612 + vfsuid_t vfsuid = i_uid_into_vfsuid(user_ns, inode); 1613 + vfsgid_t vfsgid = i_gid_into_vfsgid(user_ns, inode); 1612 1614 1613 1615 buf = (struct create_posix_rsp *)cc; 1614 1616 memset(buf, 0, sizeof(struct create_posix_rsp)); 1615 1617 buf->ccontext.DataOffset = cpu_to_le16(offsetof 1616 1618 (struct create_posix_rsp, nlink)); 1617 - buf->ccontext.DataLength = cpu_to_le32(52); 1619 + /* 1620 + * DataLength = nlink(4) + reparse_tag(4) + mode(4) + 1621 + * domain sid(28) + unix group sid(16). 1622 + */ 1623 + buf->ccontext.DataLength = cpu_to_le32(56); 1618 1624 buf->ccontext.NameOffset = cpu_to_le16(offsetof 1619 1625 (struct create_posix_rsp, Name)); 1620 1626 buf->ccontext.NameLength = cpu_to_le16(POSIX_CTXT_DATA_LEN); ··· 1644 1638 1645 1639 buf->nlink = cpu_to_le32(inode->i_nlink); 1646 1640 buf->reparse_tag = cpu_to_le32(fp->volatile_id); 1647 - buf->mode = cpu_to_le32(inode->i_mode); 1648 - id_to_sid(from_kuid_munged(&init_user_ns, 1649 - i_uid_into_mnt(user_ns, inode)), 1650 - SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]); 1651 - id_to_sid(from_kgid_munged(&init_user_ns, 1652 - i_gid_into_mnt(user_ns, inode)), 1653 - SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]); 1641 + buf->mode = cpu_to_le32(inode->i_mode & 0777); 1642 + /* 1643 + * SidBuffer(44) contain two sids(Domain sid(28), UNIX group sid(16)). 1644 + * Domain sid(28) = revision(1) + num_subauth(1) + authority(6) + 1645 + * sub_auth(4 * 4(num_subauth)) + RID(4). 1646 + * UNIX group id(16) = revision(1) + num_subauth(1) + authority(6) + 1647 + * sub_auth(4 * 1(num_subauth)) + RID(4). 1648 + */ 1649 + id_to_sid(from_kuid_munged(&init_user_ns, vfsuid_into_kuid(vfsuid)), 1650 + SIDOWNER, (struct smb_sid *)&buf->SidBuffer[0]); 1651 + id_to_sid(from_kgid_munged(&init_user_ns, vfsgid_into_kgid(vfsgid)), 1652 + SIDUNIX_GROUP, (struct smb_sid *)&buf->SidBuffer[28]); 1654 1653 } 1655 1654 1656 1655 /*
+1 -3
fs/ksmbd/server.c
··· 235 235 if (work->sess && work->sess->enc && work->encrypted && 236 236 conn->ops->encrypt_resp) { 237 237 rc = conn->ops->encrypt_resp(work); 238 - if (rc < 0) { 238 + if (rc < 0) 239 239 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR); 240 - goto send; 241 - } 242 240 } 243 241 244 242 ksmbd_conn_write(work);
+73 -53
fs/ksmbd/smb2pdu.c
··· 925 925 * 926 926 * Return: true if connection should be encrypted, else false 927 927 */ 928 - static bool smb3_encryption_negotiated(struct ksmbd_conn *conn) 928 + bool smb3_encryption_negotiated(struct ksmbd_conn *conn) 929 929 { 930 930 if (!conn->ops->generate_encryptionkey) 931 931 return false; ··· 1883 1883 goto out_err1; 1884 1884 } 1885 1885 1886 - name = ksmbd_extract_sharename(treename); 1886 + name = ksmbd_extract_sharename(conn->um, treename); 1887 1887 if (IS_ERR(name)) { 1888 1888 status.ret = KSMBD_TREE_CONN_STATUS_ERROR; 1889 1889 goto out_err1; ··· 2185 2185 * Return: 0 on success, otherwise error 2186 2186 */ 2187 2187 static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, 2188 - struct path *path) 2188 + const struct path *path) 2189 2189 { 2190 2190 struct user_namespace *user_ns = mnt_user_ns(path->mnt); 2191 2191 char *attr_name = NULL, *value; ··· 2272 2272 return rc; 2273 2273 } 2274 2274 2275 - static noinline int smb2_set_stream_name_xattr(struct path *path, 2275 + static noinline int smb2_set_stream_name_xattr(const struct path *path, 2276 2276 struct ksmbd_file *fp, 2277 2277 char *stream_name, int s_type) 2278 2278 { ··· 2311 2311 return 0; 2312 2312 } 2313 2313 2314 - static int smb2_remove_smb_xattrs(struct path *path) 2314 + static int smb2_remove_smb_xattrs(const struct path *path) 2315 2315 { 2316 2316 struct user_namespace *user_ns = mnt_user_ns(path->mnt); 2317 2317 char *name, *xattr_list = NULL; ··· 2345 2345 return err; 2346 2346 } 2347 2347 2348 - static int smb2_create_truncate(struct path *path) 2348 + static int smb2_create_truncate(const struct path *path) 2349 2349 { 2350 2350 int rc = vfs_truncate(path, 0); 2351 2351 ··· 2364 2364 return rc; 2365 2365 } 2366 2366 2367 - static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path, 2367 + static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, const struct path *path, 2368 2368 struct ksmbd_file *fp) 2369 2369 { 2370 2370 struct xattr_dos_attrib da = {0}; ··· 2387 2387 } 2388 2388 2389 2389 static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, 2390 - struct path *path, struct ksmbd_file *fp) 2390 + const struct path *path, struct ksmbd_file *fp) 2391 2391 { 2392 2392 struct xattr_dos_attrib da; 2393 2393 int rc; ··· 2447 2447 2448 2448 static int smb2_create_sd_buffer(struct ksmbd_work *work, 2449 2449 struct smb2_create_req *req, 2450 - struct path *path) 2450 + const struct path *path) 2451 2451 { 2452 2452 struct create_context *context; 2453 2453 struct create_sd_buf_req *sd_buf; ··· 2477 2477 struct user_namespace *mnt_userns, 2478 2478 struct inode *inode) 2479 2479 { 2480 - fattr->cf_uid = i_uid_into_mnt(mnt_userns, inode); 2481 - fattr->cf_gid = i_gid_into_mnt(mnt_userns, inode); 2480 + vfsuid_t vfsuid = i_uid_into_vfsuid(mnt_userns, inode); 2481 + vfsgid_t vfsgid = i_gid_into_vfsgid(mnt_userns, inode); 2482 + 2483 + fattr->cf_uid = vfsuid_into_kuid(vfsuid); 2484 + fattr->cf_gid = vfsgid_into_kgid(vfsgid); 2482 2485 fattr->cf_mode = inode->i_mode; 2483 2486 fattr->cf_acls = NULL; 2484 2487 fattr->cf_dacls = NULL; ··· 2764 2761 } else { 2765 2762 file_present = true; 2766 2763 user_ns = mnt_user_ns(path.mnt); 2767 - generic_fillattr(user_ns, d_inode(path.dentry), &stat); 2768 2764 } 2769 2765 if (stream_name) { 2770 2766 if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) { ··· 2772 2770 rsp->hdr.Status = STATUS_NOT_A_DIRECTORY; 2773 2771 } 2774 2772 } else { 2775 - if (S_ISDIR(stat.mode) && s_type == DATA_STREAM) { 2773 + if (file_present && S_ISDIR(d_inode(path.dentry)->i_mode) && 2774 + s_type == DATA_STREAM) { 2776 2775 rc = -EIO; 2777 2776 rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY; 2778 2777 } ··· 2790 2787 } 2791 2788 2792 2789 if (file_present && req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE && 2793 - S_ISDIR(stat.mode) && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { 2790 + S_ISDIR(d_inode(path.dentry)->i_mode) && 2791 + !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { 2794 2792 ksmbd_debug(SMB, "open() argument is a directory: %s, %x\n", 2795 2793 name, req->CreateOptions); 2796 2794 rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY; ··· 2801 2797 2802 2798 if (file_present && (req->CreateOptions & FILE_DIRECTORY_FILE_LE) && 2803 2799 !(req->CreateDisposition == FILE_CREATE_LE) && 2804 - !S_ISDIR(stat.mode)) { 2800 + !S_ISDIR(d_inode(path.dentry)->i_mode)) { 2805 2801 rsp->hdr.Status = STATUS_NOT_A_DIRECTORY; 2806 2802 rc = -EIO; 2807 2803 goto err_out; ··· 3565 3561 posix_info->AllocationSize = cpu_to_le64(ksmbd_kstat->kstat->blocks << 9); 3566 3562 posix_info->DeviceId = cpu_to_le32(ksmbd_kstat->kstat->rdev); 3567 3563 posix_info->HardLinks = cpu_to_le32(ksmbd_kstat->kstat->nlink); 3568 - posix_info->Mode = cpu_to_le32(ksmbd_kstat->kstat->mode); 3564 + posix_info->Mode = cpu_to_le32(ksmbd_kstat->kstat->mode & 0777); 3569 3565 posix_info->Inode = cpu_to_le64(ksmbd_kstat->kstat->ino); 3570 3566 posix_info->DosAttributes = 3571 3567 S_ISDIR(ksmbd_kstat->kstat->mode) ? 3572 3568 FILE_ATTRIBUTE_DIRECTORY_LE : FILE_ATTRIBUTE_ARCHIVE_LE; 3573 3569 if (d_info->hide_dot_file && d_info->name[0] == '.') 3574 3570 posix_info->DosAttributes |= FILE_ATTRIBUTE_HIDDEN_LE; 3571 + /* 3572 + * SidBuffer(32) contain two sids(Domain sid(16), UNIX group sid(16)). 3573 + * UNIX sid(16) = revision(1) + num_subauth(1) + authority(6) + 3574 + * sub_auth(4 * 1(num_subauth)) + RID(4). 3575 + */ 3575 3576 id_to_sid(from_kuid_munged(&init_user_ns, ksmbd_kstat->kstat->uid), 3576 - SIDNFS_USER, (struct smb_sid *)&posix_info->SidBuffer[0]); 3577 + SIDUNIX_USER, (struct smb_sid *)&posix_info->SidBuffer[0]); 3577 3578 id_to_sid(from_kgid_munged(&init_user_ns, ksmbd_kstat->kstat->gid), 3578 - SIDNFS_GROUP, (struct smb_sid *)&posix_info->SidBuffer[20]); 3579 + SIDUNIX_GROUP, (struct smb_sid *)&posix_info->SidBuffer[16]); 3579 3580 memcpy(posix_info->name, conv_name, conv_len); 3580 3581 posix_info->name_len = cpu_to_le32(conv_len); 3581 3582 posix_info->NextEntryOffset = cpu_to_le32(next_entry_offset); ··· 3815 3806 return true; 3816 3807 } 3817 3808 3818 - static void restart_ctx(struct dir_context *ctx) 3819 - { 3820 - ctx->pos = 0; 3821 - } 3822 - 3823 3809 static int verify_info_level(int info_level) 3824 3810 { 3825 3811 switch (info_level) { ··· 3896 3892 inode_permission(file_mnt_user_ns(dir_fp->filp), 3897 3893 file_inode(dir_fp->filp), 3898 3894 MAY_READ | MAY_EXEC)) { 3899 - pr_err("no right to enumerate directory (%pd)\n", 3900 - dir_fp->filp->f_path.dentry); 3895 + pr_err("no right to enumerate directory (%pD)\n", dir_fp->filp); 3901 3896 rc = -EACCES; 3902 3897 goto err_out2; 3903 3898 } ··· 3922 3919 if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) { 3923 3920 ksmbd_debug(SMB, "Restart directory scan\n"); 3924 3921 generic_file_llseek(dir_fp->filp, 0, SEEK_SET); 3925 - restart_ctx(&dir_fp->readdir_data.ctx); 3926 3922 } 3927 3923 3928 3924 memset(&d_info, 0, sizeof(struct ksmbd_dir_info)); ··· 3968 3966 */ 3969 3967 if (!d_info.out_buf_len && !d_info.num_entry) 3970 3968 goto no_buf_len; 3971 - if (rc == 0) 3972 - restart_ctx(&dir_fp->readdir_data.ctx); 3973 - if (rc == -ENOSPC) 3969 + if (rc > 0 || rc == -ENOSPC) 3974 3970 rc = 0; 3975 - if (rc) 3971 + else if (rc) 3976 3972 goto err_out; 3977 3973 3978 3974 d_info.wptr = d_info.rptr; ··· 4027 4027 rsp->hdr.Status = STATUS_NO_MEMORY; 4028 4028 else if (rc == -EFAULT) 4029 4029 rsp->hdr.Status = STATUS_INVALID_INFO_CLASS; 4030 + else if (rc == -EIO) 4031 + rsp->hdr.Status = STATUS_FILE_CORRUPT_ERROR; 4030 4032 if (!rsp->hdr.Status) 4031 4033 rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR; 4032 4034 ··· 4158 4156 int rc, name_len, value_len, xattr_list_len, idx; 4159 4157 ssize_t buf_free_len, alignment_bytes, next_offset, rsp_data_cnt = 0; 4160 4158 struct smb2_ea_info_req *ea_req = NULL; 4161 - struct path *path; 4159 + const struct path *path; 4162 4160 struct user_namespace *user_ns = file_mnt_user_ns(fp->filp); 4163 4161 4164 4162 if (!(fp->daccess & FILE_READ_EA_LE)) { ··· 4495 4493 struct smb2_file_stream_info *file_info; 4496 4494 char *stream_name, *xattr_list = NULL, *stream_buf; 4497 4495 struct kstat stat; 4498 - struct path *path = &fp->filp->f_path; 4496 + const struct path *path = &fp->filp->f_path; 4499 4497 ssize_t xattr_list_len; 4500 4498 int nbytes = 0, streamlen, stream_name_len, next, idx = 0; 4501 4499 int buf_free_len; ··· 4720 4718 { 4721 4719 struct smb311_posix_qinfo *file_info; 4722 4720 struct inode *inode = file_inode(fp->filp); 4721 + struct user_namespace *user_ns = file_mnt_user_ns(fp->filp); 4722 + vfsuid_t vfsuid = i_uid_into_vfsuid(user_ns, inode); 4723 + vfsgid_t vfsgid = i_gid_into_vfsgid(user_ns, inode); 4723 4724 u64 time; 4725 + int out_buf_len = sizeof(struct smb311_posix_qinfo) + 32; 4724 4726 4725 4727 file_info = (struct smb311_posix_qinfo *)rsp->Buffer; 4726 4728 file_info->CreationTime = cpu_to_le64(fp->create_time); ··· 4739 4733 file_info->EndOfFile = cpu_to_le64(inode->i_size); 4740 4734 file_info->AllocationSize = cpu_to_le64(inode->i_blocks << 9); 4741 4735 file_info->HardLinks = cpu_to_le32(inode->i_nlink); 4742 - file_info->Mode = cpu_to_le32(inode->i_mode); 4736 + file_info->Mode = cpu_to_le32(inode->i_mode & 0777); 4743 4737 file_info->DeviceId = cpu_to_le32(inode->i_rdev); 4744 - rsp->OutputBufferLength = 4745 - cpu_to_le32(sizeof(struct smb311_posix_qinfo)); 4746 - inc_rfc1001_len(rsp_org, sizeof(struct smb311_posix_qinfo)); 4747 - return 0; 4738 + 4739 + /* 4740 + * Sids(32) contain two sids(Domain sid(16), UNIX group sid(16)). 4741 + * UNIX sid(16) = revision(1) + num_subauth(1) + authority(6) + 4742 + * sub_auth(4 * 1(num_subauth)) + RID(4). 4743 + */ 4744 + id_to_sid(from_kuid_munged(&init_user_ns, vfsuid_into_kuid(vfsuid)), 4745 + SIDUNIX_USER, (struct smb_sid *)&file_info->Sids[0]); 4746 + id_to_sid(from_kgid_munged(&init_user_ns, vfsgid_into_kgid(vfsgid)), 4747 + SIDUNIX_GROUP, (struct smb_sid *)&file_info->Sids[16]); 4748 + 4749 + rsp->OutputBufferLength = cpu_to_le32(out_buf_len); 4750 + inc_rfc1001_len(rsp_org, out_buf_len); 4751 + return out_buf_len; 4748 4752 } 4749 4753 4750 4754 static int smb2_get_info_file(struct ksmbd_work *work, ··· 4874 4858 pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); 4875 4859 rc = -EOPNOTSUPP; 4876 4860 } else { 4877 - rc = find_file_posix_info(rsp, fp, work->response_buf); 4878 - file_infoclass_size = sizeof(struct smb311_posix_qinfo); 4861 + file_infoclass_size = find_file_posix_info(rsp, fp, 4862 + work->response_buf); 4879 4863 } 4880 4864 break; 4881 4865 default: ··· 5427 5411 if (!pathname) 5428 5412 return -ENOMEM; 5429 5413 5430 - abs_oldname = d_path(&fp->filp->f_path, pathname, PATH_MAX); 5414 + abs_oldname = file_path(fp->filp, pathname, PATH_MAX); 5431 5415 if (IS_ERR(abs_oldname)) { 5432 5416 rc = -EINVAL; 5433 5417 goto out; ··· 5562 5546 } 5563 5547 5564 5548 ksmbd_debug(SMB, "link name is %s\n", link_name); 5565 - target_name = d_path(&filp->f_path, pathname, PATH_MAX); 5549 + target_name = file_path(filp, pathname, PATH_MAX); 5566 5550 if (IS_ERR(target_name)) { 5567 5551 rc = -EINVAL; 5568 5552 goto out; ··· 6280 6264 goto out; 6281 6265 } 6282 6266 6283 - ksmbd_debug(SMB, "filename %pd, offset %lld, len %zu\n", 6284 - fp->filp->f_path.dentry, offset, length); 6267 + ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n", 6268 + fp->filp, offset, length); 6285 6269 6286 6270 work->aux_payload_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO); 6287 6271 if (!work->aux_payload_buf) { ··· 6545 6529 data_buf = (char *)(((char *)&req->hdr.ProtocolId) + 6546 6530 le16_to_cpu(req->DataOffset)); 6547 6531 6548 - ksmbd_debug(SMB, "filename %pd, offset %lld, len %zu\n", 6549 - fp->filp->f_path.dentry, offset, length); 6532 + ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n", 6533 + fp->filp, offset, length); 6550 6534 err = ksmbd_vfs_write(work, fp, data_buf, length, &offset, 6551 6535 writethrough, &nbytes); 6552 6536 if (err < 0) ··· 7657 7641 goto out; 7658 7642 } 7659 7643 7660 - if (in_buf_len < sizeof(struct validate_negotiate_info_req)) 7661 - return -EINVAL; 7644 + if (in_buf_len < offsetof(struct validate_negotiate_info_req, 7645 + Dialects)) { 7646 + ret = -EINVAL; 7647 + goto out; 7648 + } 7662 7649 7663 - if (out_buf_len < sizeof(struct validate_negotiate_info_rsp)) 7664 - return -EINVAL; 7650 + if (out_buf_len < sizeof(struct validate_negotiate_info_rsp)) { 7651 + ret = -EINVAL; 7652 + goto out; 7653 + } 7665 7654 7666 7655 ret = fsctl_validate_negotiate_info(conn, 7667 7656 (struct validate_negotiate_info_req *)&req->Buffer[0], ··· 8592 8571 buf_size += iov[1].iov_len; 8593 8572 work->resp_hdr_sz = iov[1].iov_len; 8594 8573 8595 - rc = ksmbd_crypt_message(work->conn, iov, rq_nvec, 1); 8574 + rc = ksmbd_crypt_message(work, iov, rq_nvec, 1); 8596 8575 if (rc) 8597 8576 return rc; 8598 8577 ··· 8611 8590 8612 8591 int smb3_decrypt_req(struct ksmbd_work *work) 8613 8592 { 8614 - struct ksmbd_conn *conn = work->conn; 8615 8593 struct ksmbd_session *sess; 8616 8594 char *buf = work->request_buf; 8617 8595 unsigned int pdu_length = get_rfc1002_len(buf); ··· 8630 8610 return -ECONNABORTED; 8631 8611 } 8632 8612 8633 - sess = ksmbd_session_lookup_all(conn, le64_to_cpu(tr_hdr->SessionId)); 8613 + sess = ksmbd_session_lookup_all(work->conn, le64_to_cpu(tr_hdr->SessionId)); 8634 8614 if (!sess) { 8635 8615 pr_err("invalid session id(%llx) in transform header\n", 8636 8616 le64_to_cpu(tr_hdr->SessionId)); ··· 8641 8621 iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4; 8642 8622 iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr) + 4; 8643 8623 iov[1].iov_len = buf_data_size; 8644 - rc = ksmbd_crypt_message(conn, iov, 2, 0); 8624 + rc = ksmbd_crypt_message(work, iov, 2, 0); 8645 8625 if (rc) 8646 8626 return rc; 8647 8627
+5 -2
fs/ksmbd/smb2pdu.h
··· 158 158 __le32 nlink; 159 159 __le32 reparse_tag; 160 160 __le32 mode; 161 - u8 SidBuffer[40]; 161 + /* SidBuffer contain two sids(Domain sid(28), UNIX group sid(16)) */ 162 + u8 SidBuffer[44]; 162 163 } __packed; 163 164 164 165 struct smb2_buffer_desc_v1 { ··· 440 439 __le32 HardLinks; 441 440 __le32 ReparseTag; 442 441 __le32 Mode; 443 - u8 SidBuffer[40]; 442 + /* SidBuffer contain two sids (UNIX user sid(16), UNIX group sid(16)) */ 443 + u8 SidBuffer[32]; 444 444 __le32 name_len; 445 445 u8 name[1]; 446 446 /* ··· 494 492 int smb3_encrypt_resp(struct ksmbd_work *work); 495 493 bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work); 496 494 int smb2_set_rsp_credits(struct ksmbd_work *work); 495 + bool smb3_encryption_negotiated(struct ksmbd_conn *conn); 497 496 498 497 /* smb2 misc functions */ 499 498 int ksmbd_smb2_check_message(struct ksmbd_work *work);
+4 -2
fs/ksmbd/smb_common.c
··· 4 4 * Copyright (C) 2018 Namjae Jeon <linkinjeon@kernel.org> 5 5 */ 6 6 7 + #include <linux/user_namespace.h> 8 + 7 9 #include "smb_common.h" 8 10 #include "server.h" 9 11 #include "misc.h" ··· 627 625 if (!cred) 628 626 return -ENOMEM; 629 627 630 - cred->fsuid = make_kuid(current_user_ns(), uid); 631 - cred->fsgid = make_kgid(current_user_ns(), gid); 628 + cred->fsuid = make_kuid(&init_user_ns, uid); 629 + cred->fsgid = make_kgid(&init_user_ns, gid); 632 630 633 631 gi = groups_alloc(0); 634 632 if (!gi) {
+7 -5
fs/ksmbd/smbacl.c
··· 275 275 uid_t id; 276 276 277 277 id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]); 278 - uid = mapped_kuid_user(user_ns, &init_user_ns, KUIDT_INIT(id)); 278 + uid = KUIDT_INIT(id); 279 + uid = from_vfsuid(user_ns, &init_user_ns, VFSUIDT_INIT(uid)); 279 280 if (uid_valid(uid)) { 280 281 fattr->cf_uid = uid; 281 282 rc = 0; ··· 286 285 gid_t id; 287 286 288 287 id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]); 289 - gid = mapped_kgid_user(user_ns, &init_user_ns, KGIDT_INIT(id)); 288 + gid = KGIDT_INIT(id); 289 + gid = from_vfsgid(user_ns, &init_user_ns, VFSGIDT_INIT(gid)); 290 290 if (gid_valid(gid)) { 291 291 fattr->cf_gid = gid; 292 292 rc = 0; ··· 993 991 } 994 992 995 993 int smb_inherit_dacl(struct ksmbd_conn *conn, 996 - struct path *path, 994 + const struct path *path, 997 995 unsigned int uid, unsigned int gid) 998 996 { 999 997 const struct smb_sid *psid, *creator = NULL; ··· 1187 1185 return false; 1188 1186 } 1189 1187 1190 - int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, 1188 + int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, 1191 1189 __le32 *pdaccess, int uid) 1192 1190 { 1193 1191 struct user_namespace *user_ns = mnt_user_ns(path->mnt); ··· 1354 1352 } 1355 1353 1356 1354 int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, 1357 - struct path *path, struct smb_ntsd *pntsd, int ntsd_len, 1355 + const struct path *path, struct smb_ntsd *pntsd, int ntsd_len, 1358 1356 bool type_check) 1359 1357 { 1360 1358 int rc;
+9 -9
fs/ksmbd/smbacl.h
··· 201 201 struct posix_acl_entry *pace); 202 202 int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid); 203 203 bool smb_inherit_flags(int flags, bool is_dir); 204 - int smb_inherit_dacl(struct ksmbd_conn *conn, struct path *path, 204 + int smb_inherit_dacl(struct ksmbd_conn *conn, const struct path *path, 205 205 unsigned int uid, unsigned int gid); 206 - int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, 206 + int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, 207 207 __le32 *pdaccess, int uid); 208 208 int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, 209 - struct path *path, struct smb_ntsd *pntsd, int ntsd_len, 209 + const struct path *path, struct smb_ntsd *pntsd, int ntsd_len, 210 210 bool type_check); 211 211 void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); 212 212 void ksmbd_init_domain(u32 *sub_auth); ··· 214 214 static inline uid_t posix_acl_uid_translate(struct user_namespace *mnt_userns, 215 215 struct posix_acl_entry *pace) 216 216 { 217 - kuid_t kuid; 217 + vfsuid_t vfsuid; 218 218 219 219 /* If this is an idmapped mount, apply the idmapping. */ 220 - kuid = mapped_kuid_fs(mnt_userns, &init_user_ns, pace->e_uid); 220 + vfsuid = make_vfsuid(mnt_userns, &init_user_ns, pace->e_uid); 221 221 222 222 /* Translate the kuid into a userspace id ksmbd would see. */ 223 - return from_kuid(&init_user_ns, kuid); 223 + return from_kuid(&init_user_ns, vfsuid_into_kuid(vfsuid)); 224 224 } 225 225 226 226 static inline gid_t posix_acl_gid_translate(struct user_namespace *mnt_userns, 227 227 struct posix_acl_entry *pace) 228 228 { 229 - kgid_t kgid; 229 + vfsgid_t vfsgid; 230 230 231 231 /* If this is an idmapped mount, apply the idmapping. */ 232 - kgid = mapped_kgid_fs(mnt_userns, &init_user_ns, pace->e_gid); 232 + vfsgid = make_vfsgid(mnt_userns, &init_user_ns, pace->e_gid); 233 233 234 234 /* Translate the kgid into a userspace id ksmbd would see. */ 235 - return from_kgid(&init_user_ns, kgid); 235 + return from_kgid(&init_user_ns, vfsgid_into_kgid(vfsgid)); 236 236 } 237 237 238 238 #endif /* _SMBACL_H */
+5 -3
fs/ksmbd/transport_rdma.c
··· 32 32 /* SMB_DIRECT negotiation timeout in seconds */ 33 33 #define SMB_DIRECT_NEGOTIATE_TIMEOUT 120 34 34 35 - #define SMB_DIRECT_MAX_SEND_SGES 8 35 + #define SMB_DIRECT_MAX_SEND_SGES 6 36 36 #define SMB_DIRECT_MAX_RECV_SGES 1 37 37 38 38 /* ··· 62 62 static int smb_direct_send_credit_target = 255; 63 63 64 64 /* The maximum single message size can be sent to remote peer */ 65 - static int smb_direct_max_send_size = 8192; 65 + static int smb_direct_max_send_size = 1364; 66 66 67 67 /* The maximum fragmented upper-layer payload receive size supported */ 68 68 static int smb_direct_max_fragmented_recv_size = 1024 * 1024; 69 69 70 70 /* The maximum single-message size which can be received */ 71 - static int smb_direct_max_receive_size = 8192; 71 + static int smb_direct_max_receive_size = 1364; 72 72 73 73 static int smb_direct_max_read_write_size = SMBD_DEFAULT_IOSIZE; 74 74 ··· 1527 1527 } 1528 1528 case RDMA_CM_EVENT_DEVICE_REMOVAL: 1529 1529 case RDMA_CM_EVENT_DISCONNECTED: { 1530 + ib_drain_qp(t->qp); 1531 + 1530 1532 t->status = SMB_DIRECT_CS_DISCONNECTED; 1531 1533 wake_up_interruptible(&t->wait_status); 1532 1534 wake_up_interruptible(&t->wait_reassembly_queue);
+2 -1
fs/ksmbd/transport_tcp.c
··· 399 399 400 400 ret = sock_create(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &ksmbd_socket); 401 401 if (ret) { 402 - pr_err("Can't create socket for ipv6, try ipv4: %d\n", ret); 402 + if (ret != -EAFNOSUPPORT) 403 + pr_err("Can't create socket for ipv6, fallback to ipv4: %d\n", ret); 403 404 ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, 404 405 &ksmbd_socket); 405 406 if (ret) {
+2 -1
fs/ksmbd/unicode.h
··· 24 24 #include <asm/byteorder.h> 25 25 #include <linux/types.h> 26 26 #include <linux/nls.h> 27 + #include <linux/unicode.h> 27 28 28 29 #define UNIUPR_NOLOWER /* Example to not expand lower case tables */ 29 30 ··· 70 69 const struct nls_table *codepage); 71 70 int smbConvertToUTF16(__le16 *target, const char *source, int srclen, 72 71 const struct nls_table *cp, int mapchars); 73 - char *ksmbd_extract_sharename(char *treename); 72 + char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename); 74 73 #endif 75 74 76 75 /*
+24 -12
fs/ksmbd/vfs.c
··· 377 377 378 378 if (work->conn->connection_type) { 379 379 if (!(fp->daccess & (FILE_READ_DATA_LE | FILE_EXECUTE_LE))) { 380 - pr_err("no right to read(%pd)\n", 381 - fp->filp->f_path.dentry); 380 + pr_err("no right to read(%pD)\n", fp->filp); 382 381 return -EACCES; 383 382 } 384 383 } ··· 486 487 487 488 if (work->conn->connection_type) { 488 489 if (!(fp->daccess & FILE_WRITE_DATA_LE)) { 489 - pr_err("no right to write(%pd)\n", 490 - fp->filp->f_path.dentry); 490 + pr_err("no right to write(%pD)\n", fp->filp); 491 491 err = -EACCES; 492 492 goto out; 493 493 } ··· 525 527 if (sync) { 526 528 err = vfs_fsync_range(filp, offset, offset + *written, 0); 527 529 if (err < 0) 528 - pr_err("fsync failed for filename = %pd, err = %d\n", 529 - fp->filp->f_path.dentry, err); 530 + pr_err("fsync failed for filename = %pD, err = %d\n", 531 + fp->filp, err); 530 532 } 531 533 532 534 out: ··· 541 543 * 542 544 * Return: 0 on success, otherwise error 543 545 */ 544 - int ksmbd_vfs_getattr(struct path *path, struct kstat *stat) 546 + int ksmbd_vfs_getattr(const struct path *path, struct kstat *stat) 545 547 { 546 548 int err; 547 549 ··· 1143 1145 unsigned int d_type) 1144 1146 { 1145 1147 struct ksmbd_readdir_data *buf; 1148 + int cmp = -EINVAL; 1146 1149 1147 1150 buf = container_of(ctx, struct ksmbd_readdir_data, ctx); 1148 1151 1149 1152 if (buf->used != namlen) 1150 1153 return true; 1151 - if (!strncasecmp((char *)buf->private, name, namlen)) { 1154 + if (IS_ENABLED(CONFIG_UNICODE) && buf->um) { 1155 + const struct qstr q_buf = {.name = buf->private, 1156 + .len = buf->used}; 1157 + const struct qstr q_name = {.name = name, 1158 + .len = namlen}; 1159 + 1160 + cmp = utf8_strncasecmp(buf->um, &q_buf, &q_name); 1161 + } 1162 + if (cmp < 0) 1163 + cmp = strncasecmp((char *)buf->private, name, namlen); 1164 + if (!cmp) { 1152 1165 memcpy((char *)buf->private, name, namlen); 1153 1166 buf->dirent_count = 1; 1154 1167 return false; ··· 1175 1166 * 1176 1167 * Return: 0 on success, otherwise error 1177 1168 */ 1178 - static int ksmbd_vfs_lookup_in_dir(struct path *dir, char *name, size_t namelen) 1169 + static int ksmbd_vfs_lookup_in_dir(const struct path *dir, char *name, 1170 + size_t namelen, struct unicode_map *um) 1179 1171 { 1180 1172 int ret; 1181 1173 struct file *dfilp; ··· 1186 1176 .private = name, 1187 1177 .used = namelen, 1188 1178 .dirent_count = 0, 1179 + .um = um, 1189 1180 }; 1190 1181 1191 1182 dfilp = dentry_open(dir, flags, current_cred()); ··· 1249 1238 break; 1250 1239 1251 1240 err = ksmbd_vfs_lookup_in_dir(&parent, filename, 1252 - filename_len); 1241 + filename_len, 1242 + work->conn->um); 1253 1243 path_put(&parent); 1254 1244 if (err) 1255 1245 goto out; ··· 1753 1741 *total_size_written = 0; 1754 1742 1755 1743 if (!(src_fp->daccess & (FILE_READ_DATA_LE | FILE_EXECUTE_LE))) { 1756 - pr_err("no right to read(%pd)\n", src_fp->filp->f_path.dentry); 1744 + pr_err("no right to read(%pD)\n", src_fp->filp); 1757 1745 return -EACCES; 1758 1746 } 1759 1747 if (!(dst_fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE))) { 1760 - pr_err("no right to write(%pd)\n", dst_fp->filp->f_path.dentry); 1748 + pr_err("no right to write(%pD)\n", dst_fp->filp); 1761 1749 return -EACCES; 1762 1750 } 1763 1751
+3 -1
fs/ksmbd/vfs.h
··· 12 12 #include <linux/namei.h> 13 13 #include <uapi/linux/xattr.h> 14 14 #include <linux/posix_acl.h> 15 + #include <linux/unicode.h> 15 16 16 17 #include "smbacl.h" 17 18 #include "xattr.h" ··· 61 60 unsigned int used; 62 61 unsigned int dirent_count; 63 62 unsigned int file_attr; 63 + struct unicode_map *um; 64 64 }; 65 65 66 66 /* ksmbd kstat wrapper to get valid create time when reading dir entry */ ··· 87 85 int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name); 88 86 int ksmbd_vfs_link(struct ksmbd_work *work, 89 87 const char *oldname, const char *newname); 90 - int ksmbd_vfs_getattr(struct path *path, struct kstat *stat); 88 + int ksmbd_vfs_getattr(const struct path *path, struct kstat *stat); 91 89 int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, 92 90 char *newname); 93 91 int ksmbd_vfs_truncate(struct ksmbd_work *work,