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

Merge tag '6.6-rc-ksmbd-fixes-part1' of git://git.samba.org/ksmbd

Pull smb server updates from Steve French:

- fix potential overflows in decoding create and in session setup
requests

- cleanup fixes

- compounding fixes, including one for MacOS compounded read requests

- session setup error handling fix

- fix mode bit bug when applying force_directory_mode and
force_create_mode

- RDMA (smbdirect) write fix

* tag '6.6-rc-ksmbd-fixes-part1' of git://git.samba.org/ksmbd:
ksmbd: add missing calling smb2_set_err_rsp() on error
ksmbd: replace one-element array with flex-array member in struct smb2_ea_info
ksmbd: fix slub overflow in ksmbd_decode_ntlmssp_auth_blob()
ksmbd: fix wrong DataOffset validation of create context
ksmbd: Fix one kernel-doc comment
ksmbd: reduce descriptor size if remaining bytes is less than request size
ksmbd: fix `force create mode' and `force directory mode'
ksmbd: fix wrong interim response on compound
ksmbd: add support for read compound
ksmbd: switch to use kmemdup_nul() helper

+432 -417
+1 -3
fs/smb/server/asn1.c
··· 214 214 { 215 215 struct ksmbd_conn *conn = context; 216 216 217 - conn->mechToken = kmalloc(vlen + 1, GFP_KERNEL); 217 + conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL); 218 218 if (!conn->mechToken) 219 219 return -ENOMEM; 220 220 221 - memcpy(conn->mechToken, value, vlen); 222 - conn->mechToken[vlen] = '\0'; 223 221 return 0; 224 222 } 225 223
+12 -2
fs/smb/server/auth.c
··· 355 355 if (blob_len < (u64)sess_key_off + sess_key_len) 356 356 return -EINVAL; 357 357 358 + if (sess_key_len > CIFS_KEY_SIZE) 359 + return -EINVAL; 360 + 358 361 ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL); 359 362 if (!ctx_arc4) 360 363 return -ENOMEM; ··· 1032 1029 { 1033 1030 struct scatterlist *sg; 1034 1031 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20; 1035 - int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0; 1032 + int i, *nr_entries, total_entries = 0, sg_idx = 0; 1036 1033 1037 1034 if (!nvec) 1035 + return NULL; 1036 + 1037 + nr_entries = kcalloc(nvec, sizeof(int), GFP_KERNEL); 1038 + if (!nr_entries) 1038 1039 return NULL; 1039 1040 1040 1041 for (i = 0; i < nvec - 1; i++) { ··· 1058 1051 total_entries += 2; 1059 1052 1060 1053 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL); 1061 - if (!sg) 1054 + if (!sg) { 1055 + kfree(nr_entries); 1062 1056 return NULL; 1057 + } 1063 1058 1064 1059 sg_init_table(sg, total_entries); 1065 1060 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len); ··· 1095 1086 } 1096 1087 } 1097 1088 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE); 1089 + kfree(nr_entries); 1098 1090 return sg; 1099 1091 } 1100 1092
+15 -40
fs/smb/server/connection.c
··· 123 123 } 124 124 } 125 125 126 - int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work) 126 + void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work) 127 127 { 128 128 struct ksmbd_conn *conn = work->conn; 129 - int ret = 1; 130 129 131 130 if (list_empty(&work->request_entry) && 132 131 list_empty(&work->async_request_entry)) 133 - return 0; 132 + return; 134 133 135 - if (!work->multiRsp) 136 - atomic_dec(&conn->req_running); 137 - if (!work->multiRsp) { 138 - spin_lock(&conn->request_lock); 139 - list_del_init(&work->request_entry); 140 - spin_unlock(&conn->request_lock); 141 - if (work->asynchronous) 142 - release_async_work(work); 143 - ret = 0; 144 - } 134 + atomic_dec(&conn->req_running); 135 + spin_lock(&conn->request_lock); 136 + list_del_init(&work->request_entry); 137 + spin_unlock(&conn->request_lock); 138 + if (work->asynchronous) 139 + release_async_work(work); 145 140 146 141 wake_up_all(&conn->req_running_q); 147 - return ret; 148 142 } 149 143 150 144 void ksmbd_conn_lock(struct ksmbd_conn *conn) ··· 187 193 int ksmbd_conn_write(struct ksmbd_work *work) 188 194 { 189 195 struct ksmbd_conn *conn = work->conn; 190 - size_t len = 0; 191 196 int sent; 192 - struct kvec iov[3]; 193 - int iov_idx = 0; 194 197 195 198 if (!work->response_buf) { 196 199 pr_err("NULL response header\n"); 197 200 return -EINVAL; 198 201 } 199 202 200 - if (work->tr_buf) { 201 - iov[iov_idx] = (struct kvec) { work->tr_buf, 202 - sizeof(struct smb2_transform_hdr) + 4 }; 203 - len += iov[iov_idx++].iov_len; 204 - } 205 - 206 - if (work->aux_payload_sz) { 207 - iov[iov_idx] = (struct kvec) { work->response_buf, work->resp_hdr_sz }; 208 - len += iov[iov_idx++].iov_len; 209 - iov[iov_idx] = (struct kvec) { work->aux_payload_buf, work->aux_payload_sz }; 210 - len += iov[iov_idx++].iov_len; 211 - } else { 212 - if (work->tr_buf) 213 - iov[iov_idx].iov_len = work->resp_hdr_sz; 214 - else 215 - iov[iov_idx].iov_len = get_rfc1002_len(work->response_buf) + 4; 216 - iov[iov_idx].iov_base = work->response_buf; 217 - len += iov[iov_idx++].iov_len; 218 - } 203 + if (work->send_no_response) 204 + return 0; 219 205 220 206 ksmbd_conn_lock(conn); 221 - sent = conn->transport->ops->writev(conn->transport, &iov[0], 222 - iov_idx, len, 223 - work->need_invalidate_rkey, 224 - work->remote_key); 207 + sent = conn->transport->ops->writev(conn->transport, work->iov, 208 + work->iov_cnt, 209 + get_rfc1002_len(work->iov[0].iov_base) + 4, 210 + work->need_invalidate_rkey, 211 + work->remote_key); 225 212 ksmbd_conn_unlock(conn); 226 213 227 214 if (sent < 0) {
+1 -1
fs/smb/server/connection.h
··· 158 158 struct smb2_buffer_desc_v1 *desc, 159 159 unsigned int desc_len); 160 160 void ksmbd_conn_enqueue_request(struct ksmbd_work *work); 161 - int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work); 161 + void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work); 162 162 void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops); 163 163 int ksmbd_conn_handler_loop(void *p); 164 164 int ksmbd_conn_transport_init(void);
+92 -1
fs/smb/server/ksmbd_work.c
··· 27 27 INIT_LIST_HEAD(&work->async_request_entry); 28 28 INIT_LIST_HEAD(&work->fp_entry); 29 29 INIT_LIST_HEAD(&work->interim_entry); 30 + INIT_LIST_HEAD(&work->aux_read_list); 31 + work->iov_alloc_cnt = 4; 32 + work->iov = kcalloc(work->iov_alloc_cnt, sizeof(struct kvec), 33 + GFP_KERNEL); 34 + if (!work->iov) { 35 + kmem_cache_free(work_cache, work); 36 + work = NULL; 37 + } 30 38 } 31 39 return work; 32 40 } 33 41 34 42 void ksmbd_free_work_struct(struct ksmbd_work *work) 35 43 { 44 + struct aux_read *ar, *tmp; 45 + 36 46 WARN_ON(work->saved_cred != NULL); 37 47 38 48 kvfree(work->response_buf); 39 - kvfree(work->aux_payload_buf); 49 + 50 + list_for_each_entry_safe(ar, tmp, &work->aux_read_list, entry) { 51 + kvfree(ar->buf); 52 + list_del(&ar->entry); 53 + kfree(ar); 54 + } 55 + 40 56 kfree(work->tr_buf); 41 57 kvfree(work->request_buf); 58 + kfree(work->iov); 42 59 if (work->async_id) 43 60 ksmbd_release_id(&work->conn->async_ida, work->async_id); 44 61 kmem_cache_free(work_cache, work); ··· 93 76 bool ksmbd_queue_work(struct ksmbd_work *work) 94 77 { 95 78 return queue_work(ksmbd_wq, &work->work); 79 + } 80 + 81 + static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib, 82 + unsigned int ib_len) 83 + { 84 + 85 + if (work->iov_alloc_cnt <= work->iov_cnt) { 86 + struct kvec *new; 87 + 88 + work->iov_alloc_cnt += 4; 89 + new = krealloc(work->iov, 90 + sizeof(struct kvec) * work->iov_alloc_cnt, 91 + GFP_KERNEL | __GFP_ZERO); 92 + if (!new) 93 + return -ENOMEM; 94 + work->iov = new; 95 + } 96 + 97 + work->iov[++work->iov_idx].iov_base = ib; 98 + work->iov[work->iov_idx].iov_len = ib_len; 99 + work->iov_cnt++; 100 + 101 + return 0; 102 + } 103 + 104 + static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, 105 + void *aux_buf, unsigned int aux_size) 106 + { 107 + /* Plus rfc_length size on first iov */ 108 + if (!work->iov_idx) { 109 + work->iov[work->iov_idx].iov_base = work->response_buf; 110 + *(__be32 *)work->iov[0].iov_base = 0; 111 + work->iov[work->iov_idx].iov_len = 4; 112 + work->iov_cnt++; 113 + } 114 + 115 + ksmbd_realloc_iov_pin(work, ib, len); 116 + inc_rfc1001_len(work->iov[0].iov_base, len); 117 + 118 + if (aux_size) { 119 + struct aux_read *ar; 120 + 121 + ksmbd_realloc_iov_pin(work, aux_buf, aux_size); 122 + inc_rfc1001_len(work->iov[0].iov_base, aux_size); 123 + 124 + ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL); 125 + if (!ar) 126 + return -ENOMEM; 127 + 128 + ar->buf = aux_buf; 129 + list_add(&ar->entry, &work->aux_read_list); 130 + } 131 + 132 + return 0; 133 + } 134 + 135 + int ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len) 136 + { 137 + return __ksmbd_iov_pin_rsp(work, ib, len, NULL, 0); 138 + } 139 + 140 + int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len, 141 + void *aux_buf, unsigned int aux_size) 142 + { 143 + return __ksmbd_iov_pin_rsp(work, ib, len, aux_buf, aux_size); 144 + } 145 + 146 + int allocate_interim_rsp_buf(struct ksmbd_work *work) 147 + { 148 + work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, GFP_KERNEL); 149 + if (!work->response_buf) 150 + return -ENOMEM; 151 + work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; 152 + return 0; 96 153 }
+26 -8
fs/smb/server/ksmbd_work.h
··· 19 19 KSMBD_WORK_CLOSED, 20 20 }; 21 21 22 + struct aux_read { 23 + void *buf; 24 + struct list_head entry; 25 + }; 26 + 22 27 /* one of these for every pending CIFS request at the connection */ 23 28 struct ksmbd_work { 24 29 /* Server corresponding to this mid */ ··· 36 31 /* Response buffer */ 37 32 void *response_buf; 38 33 39 - /* Read data buffer */ 40 - void *aux_payload_buf; 34 + struct list_head aux_read_list; 35 + 36 + struct kvec *iov; 37 + int iov_alloc_cnt; 38 + int iov_cnt; 39 + int iov_idx; 41 40 42 41 /* Next cmd hdr in compound req buf*/ 43 42 int next_smb2_rcv_hdr_off; 44 43 /* Next cmd hdr in compound rsp buf*/ 45 44 int next_smb2_rsp_hdr_off; 45 + /* Current cmd hdr in compound rsp buf*/ 46 + int curr_smb2_rsp_hdr_off; 46 47 47 48 /* 48 49 * Current Local FID assigned compound response if SMB2 CREATE ··· 64 53 unsigned int credits_granted; 65 54 66 55 /* response smb header size */ 67 - unsigned int resp_hdr_sz; 68 56 unsigned int response_sz; 69 - /* Read data count */ 70 - unsigned int aux_payload_sz; 71 57 72 58 void *tr_buf; 73 59 74 60 unsigned char state; 75 - /* Multiple responses for one request e.g. SMB ECHO */ 76 - bool multiRsp:1; 77 61 /* No response for cancelled request */ 78 62 bool send_no_response:1; 79 63 /* Request is encrypted */ ··· 102 96 } 103 97 104 98 /** 99 + * ksmbd_resp_buf_curr - Get current buffer on compound response. 100 + * @work: smb work containing response buffer 101 + */ 102 + static inline void *ksmbd_resp_buf_curr(struct ksmbd_work *work) 103 + { 104 + return work->response_buf + work->curr_smb2_rsp_hdr_off + 4; 105 + } 106 + 107 + /** 105 108 * ksmbd_req_buf_next - Get next buffer on compound request. 106 109 * @work: smb work containing response buffer 107 110 */ ··· 128 113 int ksmbd_workqueue_init(void); 129 114 void ksmbd_workqueue_destroy(void); 130 115 bool ksmbd_queue_work(struct ksmbd_work *work); 131 - 116 + int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len, 117 + void *aux_buf, unsigned int aux_size); 118 + int ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len); 119 + int allocate_interim_rsp_buf(struct ksmbd_work *work); 132 120 #endif /* __KSMBD_WORK_H__ */
+11 -18
fs/smb/server/mgmt/share_config.h
··· 34 34 #define KSMBD_SHARE_INVALID_UID ((__u16)-1) 35 35 #define KSMBD_SHARE_INVALID_GID ((__u16)-1) 36 36 37 - static inline int share_config_create_mode(struct ksmbd_share_config *share, 38 - umode_t posix_mode) 37 + static inline umode_t 38 + share_config_create_mode(struct ksmbd_share_config *share, 39 + umode_t posix_mode) 39 40 { 40 - if (!share->force_create_mode) { 41 - if (!posix_mode) 42 - return share->create_mask; 43 - else 44 - return posix_mode & share->create_mask; 45 - } 46 - return share->force_create_mode & share->create_mask; 41 + umode_t mode = (posix_mode ?: (umode_t)-1) & share->create_mask; 42 + 43 + return mode | share->force_create_mode; 47 44 } 48 45 49 - static inline int share_config_directory_mode(struct ksmbd_share_config *share, 50 - umode_t posix_mode) 46 + static inline umode_t 47 + share_config_directory_mode(struct ksmbd_share_config *share, 48 + umode_t posix_mode) 51 49 { 52 - if (!share->force_directory_mode) { 53 - if (!posix_mode) 54 - return share->directory_mask; 55 - else 56 - return posix_mode & share->directory_mask; 57 - } 50 + umode_t mode = (posix_mode ?: (umode_t)-1) & share->directory_mask; 58 51 59 - return share->force_directory_mode & share->directory_mask; 52 + return mode | share->force_directory_mode; 60 53 } 61 54 62 55 static inline int test_share_config_flag(struct ksmbd_share_config *share,
+10 -21
fs/smb/server/oplock.c
··· 616 616 return 0; 617 617 } 618 618 619 - static inline int allocate_oplock_break_buf(struct ksmbd_work *work) 620 - { 621 - work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, GFP_KERNEL); 622 - if (!work->response_buf) 623 - return -ENOMEM; 624 - work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; 625 - return 0; 626 - } 627 - 628 619 /** 629 620 * __smb2_oplock_break_noti() - send smb2 oplock break cmd from conn 630 621 * to client ··· 630 639 { 631 640 struct smb2_oplock_break *rsp = NULL; 632 641 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work); 633 - struct ksmbd_conn *conn = work->conn; 634 642 struct oplock_break_info *br_info = work->request_buf; 635 643 struct smb2_hdr *rsp_hdr; 636 644 struct ksmbd_file *fp; ··· 638 648 if (!fp) 639 649 goto out; 640 650 641 - if (allocate_oplock_break_buf(work)) { 651 + if (allocate_interim_rsp_buf(work)) { 642 652 pr_err("smb2_allocate_rsp_buf failed! "); 643 653 ksmbd_fd_put(work, fp); 644 654 goto out; ··· 646 656 647 657 rsp_hdr = smb2_get_msg(work->response_buf); 648 658 memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); 649 - *(__be32 *)work->response_buf = 650 - cpu_to_be32(conn->vals->header_size); 651 659 rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; 652 660 rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; 653 661 rsp_hdr->CreditRequest = cpu_to_le16(0); ··· 672 684 rsp->PersistentFid = fp->persistent_id; 673 685 rsp->VolatileFid = fp->volatile_id; 674 686 675 - inc_rfc1001_len(work->response_buf, 24); 687 + ksmbd_fd_put(work, fp); 688 + if (ksmbd_iov_pin_rsp(work, (void *)rsp, 689 + sizeof(struct smb2_oplock_break))) 690 + goto out; 676 691 677 692 ksmbd_debug(OPLOCK, 678 693 "sending oplock break v_id %llu p_id = %llu lock level = %d\n", 679 694 rsp->VolatileFid, rsp->PersistentFid, rsp->OplockLevel); 680 695 681 - ksmbd_fd_put(work, fp); 682 696 ksmbd_conn_write(work); 683 697 684 698 out: ··· 741 751 struct smb2_lease_break *rsp = NULL; 742 752 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work); 743 753 struct lease_break_info *br_info = work->request_buf; 744 - struct ksmbd_conn *conn = work->conn; 745 754 struct smb2_hdr *rsp_hdr; 746 755 747 - if (allocate_oplock_break_buf(work)) { 756 + if (allocate_interim_rsp_buf(work)) { 748 757 ksmbd_debug(OPLOCK, "smb2_allocate_rsp_buf failed! "); 749 758 goto out; 750 759 } 751 760 752 761 rsp_hdr = smb2_get_msg(work->response_buf); 753 762 memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); 754 - *(__be32 *)work->response_buf = 755 - cpu_to_be32(conn->vals->header_size); 756 763 rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; 757 764 rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; 758 765 rsp_hdr->CreditRequest = cpu_to_le16(0); ··· 778 791 rsp->AccessMaskHint = 0; 779 792 rsp->ShareMaskHint = 0; 780 793 781 - inc_rfc1001_len(work->response_buf, 44); 794 + if (ksmbd_iov_pin_rsp(work, (void *)rsp, 795 + sizeof(struct smb2_lease_break))) 796 + goto out; 782 797 783 798 ksmbd_conn_write(work); 784 799 ··· 1481 1492 name_len < 4 || 1482 1493 name_off + name_len > cc_len || 1483 1494 (value_off & 0x7) != 0 || 1484 - (value_off && (value_off < name_off + name_len)) || 1495 + (value_len && value_off < name_off + (name_len < 8 ? 8 : name_len)) || 1485 1496 ((u64)value_off + value_len > cc_len)) 1486 1497 return ERR_PTR(-EINVAL); 1487 1498
+4 -4
fs/smb/server/server.c
··· 163 163 { 164 164 u16 command = 0; 165 165 int rc; 166 + bool is_chained = false; 166 167 167 168 if (conn->ops->allocate_rsp_buf(work)) 168 169 return; ··· 230 229 } 231 230 } 232 231 232 + is_chained = is_chained_smb2_message(work); 233 + 233 234 if (work->sess && 234 235 (work->sess->sign || smb3_11_final_sess_setup_resp(work) || 235 236 conn->ops->is_sign_req(work, command))) 236 237 conn->ops->set_sign_rsp(work); 237 - } while (is_chained_smb2_message(work)); 238 - 239 - if (work->send_no_response) 240 - return; 238 + } while (is_chained == true); 241 239 242 240 send: 243 241 smb3_preauth_hash_rsp(work);
+232 -295
fs/smb/server/smb2pdu.c
··· 145 145 err_rsp = smb2_get_msg(work->response_buf); 146 146 147 147 if (err_rsp->hdr.Status != STATUS_STOPPED_ON_SYMLINK) { 148 + int err; 149 + 148 150 err_rsp->StructureSize = SMB2_ERROR_STRUCTURE_SIZE2_LE; 149 151 err_rsp->ErrorContextCount = 0; 150 152 err_rsp->Reserved = 0; 151 153 err_rsp->ByteCount = 0; 152 154 err_rsp->ErrorData[0] = 0; 153 - inc_rfc1001_len(work->response_buf, SMB2_ERROR_STRUCTURE_SIZE2); 155 + err = ksmbd_iov_pin_rsp(work, (void *)err_rsp, 156 + __SMB2_HEADER_STRUCTURE_SIZE + 157 + SMB2_ERROR_STRUCTURE_SIZE2); 158 + if (err) 159 + work->send_no_response = 1; 154 160 } 155 161 } 156 162 ··· 251 245 struct smb2_hdr *rsp_hdr; 252 246 struct smb2_negotiate_rsp *rsp; 253 247 struct ksmbd_conn *conn = work->conn; 254 - 255 - *(__be32 *)work->response_buf = 256 - cpu_to_be32(conn->vals->header_size); 248 + int err; 257 249 258 250 rsp_hdr = smb2_get_msg(work->response_buf); 259 251 memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); ··· 290 286 rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH); 291 287 ksmbd_copy_gss_neg_header((char *)(&rsp->hdr) + 292 288 le16_to_cpu(rsp->SecurityBufferOffset)); 293 - inc_rfc1001_len(work->response_buf, 294 - sizeof(struct smb2_negotiate_rsp) - 295 - sizeof(struct smb2_hdr) + AUTH_GSS_LENGTH); 296 289 rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE; 297 290 if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY) 298 291 rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE; 292 + err = ksmbd_iov_pin_rsp(work, rsp, 293 + sizeof(struct smb2_negotiate_rsp) + AUTH_GSS_LENGTH); 294 + if (err) 295 + return err; 299 296 conn->use_spnego = true; 300 297 301 298 ksmbd_conn_set_need_negotiate(conn); ··· 395 390 next_hdr_offset = le32_to_cpu(req->NextCommand); 396 391 397 392 new_len = ALIGN(len, 8); 398 - inc_rfc1001_len(work->response_buf, 399 - sizeof(struct smb2_hdr) + new_len - len); 393 + work->iov[work->iov_idx].iov_len += (new_len - len); 394 + inc_rfc1001_len(work->response_buf, new_len - len); 400 395 rsp->NextCommand = cpu_to_le32(new_len); 401 396 402 397 work->next_smb2_rcv_hdr_off += next_hdr_offset; 398 + work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off; 403 399 work->next_smb2_rsp_hdr_off += new_len; 404 400 ksmbd_debug(SMB, 405 401 "Compound req new_len = %d rcv off = %d rsp off = %d\n", ··· 476 470 len = len - get_rfc1002_len(work->response_buf); 477 471 if (len) { 478 472 ksmbd_debug(SMB, "padding len %u\n", len); 473 + work->iov[work->iov_idx].iov_len += len; 479 474 inc_rfc1001_len(work->response_buf, len); 480 - if (work->aux_payload_sz) 481 - work->aux_payload_sz += len; 482 475 } 476 + work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off; 483 477 } 484 478 return false; 485 479 } ··· 494 488 { 495 489 struct smb2_hdr *rsp_hdr = smb2_get_msg(work->response_buf); 496 490 struct smb2_hdr *rcv_hdr = smb2_get_msg(work->request_buf); 497 - struct ksmbd_conn *conn = work->conn; 498 491 499 492 memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); 500 - *(__be32 *)work->response_buf = 501 - cpu_to_be32(conn->vals->header_size); 502 493 rsp_hdr->ProtocolId = rcv_hdr->ProtocolId; 503 494 rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; 504 495 rsp_hdr->Command = rcv_hdr->Command; ··· 660 657 struct ksmbd_conn *conn = work->conn; 661 658 int id; 662 659 663 - rsp_hdr = smb2_get_msg(work->response_buf); 660 + rsp_hdr = ksmbd_resp_buf_next(work); 664 661 rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND; 665 662 666 663 id = ksmbd_acquire_async_msg_id(&conn->async_ida); ··· 709 706 void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status) 710 707 { 711 708 struct smb2_hdr *rsp_hdr; 709 + struct ksmbd_work *in_work = ksmbd_alloc_work_struct(); 712 710 713 - rsp_hdr = smb2_get_msg(work->response_buf); 714 - smb2_set_err_rsp(work); 711 + if (allocate_interim_rsp_buf(in_work)) { 712 + pr_err("smb_allocate_rsp_buf failed!\n"); 713 + ksmbd_free_work_struct(in_work); 714 + return; 715 + } 716 + 717 + in_work->conn = work->conn; 718 + memcpy(smb2_get_msg(in_work->response_buf), ksmbd_resp_buf_next(work), 719 + __SMB2_HEADER_STRUCTURE_SIZE); 720 + 721 + rsp_hdr = smb2_get_msg(in_work->response_buf); 722 + smb2_set_err_rsp(in_work); 715 723 rsp_hdr->Status = status; 716 724 717 - work->multiRsp = 1; 718 - ksmbd_conn_write(work); 719 - rsp_hdr->Status = 0; 720 - work->multiRsp = 0; 725 + ksmbd_conn_write(in_work); 726 + ksmbd_free_work_struct(in_work); 721 727 } 722 728 723 729 static __le32 smb2_get_reparse_tag_special_file(umode_t mode) ··· 833 821 pneg_ctxt->Name[15] = 0x7C; 834 822 } 835 823 836 - static void assemble_neg_contexts(struct ksmbd_conn *conn, 837 - struct smb2_negotiate_rsp *rsp, 838 - void *smb2_buf_len) 824 + static unsigned int assemble_neg_contexts(struct ksmbd_conn *conn, 825 + struct smb2_negotiate_rsp *rsp) 839 826 { 840 827 char * const pneg_ctxt = (char *)rsp + 841 828 le32_to_cpu(rsp->NegotiateContextOffset); ··· 845 834 "assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n"); 846 835 build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt, 847 836 conn->preauth_info->Preauth_HashId); 848 - inc_rfc1001_len(smb2_buf_len, AUTH_GSS_PADDING); 849 837 ctxt_size = sizeof(struct smb2_preauth_neg_context); 850 838 851 839 if (conn->cipher_type) { ··· 884 874 } 885 875 886 876 rsp->NegotiateContextCount = cpu_to_le16(neg_ctxt_cnt); 887 - inc_rfc1001_len(smb2_buf_len, ctxt_size); 877 + return ctxt_size + AUTH_GSS_PADDING; 888 878 } 889 879 890 880 static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn, ··· 1100 1090 struct smb2_negotiate_req *req = smb2_get_msg(work->request_buf); 1101 1091 struct smb2_negotiate_rsp *rsp = smb2_get_msg(work->response_buf); 1102 1092 int rc = 0; 1103 - unsigned int smb2_buf_len, smb2_neg_size; 1093 + unsigned int smb2_buf_len, smb2_neg_size, neg_ctxt_len = 0; 1104 1094 __le32 status; 1105 1095 1106 1096 ksmbd_debug(SMB, "Received negotiate request\n"); ··· 1193 1183 conn->preauth_info->Preauth_HashValue); 1194 1184 rsp->NegotiateContextOffset = 1195 1185 cpu_to_le32(OFFSET_OF_NEG_CONTEXT); 1196 - assemble_neg_contexts(conn, rsp, work->response_buf); 1186 + neg_ctxt_len = assemble_neg_contexts(conn, rsp); 1197 1187 break; 1198 1188 case SMB302_PROT_ID: 1199 1189 init_smb3_02_server(conn); ··· 1243 1233 rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH); 1244 1234 ksmbd_copy_gss_neg_header((char *)(&rsp->hdr) + 1245 1235 le16_to_cpu(rsp->SecurityBufferOffset)); 1246 - inc_rfc1001_len(work->response_buf, sizeof(struct smb2_negotiate_rsp) - 1247 - sizeof(struct smb2_hdr) + AUTH_GSS_LENGTH); 1236 + 1248 1237 rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE; 1249 1238 conn->use_spnego = true; 1250 1239 ··· 1261 1252 ksmbd_conn_set_need_negotiate(conn); 1262 1253 1263 1254 err_out: 1255 + if (rc) 1256 + rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; 1257 + 1258 + if (!rc) 1259 + rc = ksmbd_iov_pin_rsp(work, rsp, 1260 + sizeof(struct smb2_negotiate_rsp) + 1261 + AUTH_GSS_LENGTH + neg_ctxt_len); 1264 1262 if (rc < 0) 1265 1263 smb2_set_err_rsp(work); 1266 - 1267 1264 return rc; 1268 1265 } 1269 1266 ··· 1469 1454 memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len); 1470 1455 rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len); 1471 1456 kfree(spnego_blob); 1472 - inc_rfc1001_len(work->response_buf, spnego_blob_len - 1); 1473 1457 } 1474 1458 1475 1459 user = session_user(conn, req); ··· 1614 1600 return -EINVAL; 1615 1601 } 1616 1602 rsp->SecurityBufferLength = cpu_to_le16(out_len); 1617 - inc_rfc1001_len(work->response_buf, out_len - 1); 1618 1603 1619 1604 if ((conn->sign || server_conf.enforced_signing) || 1620 1605 (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) ··· 1685 1672 rsp->SessionFlags = 0; 1686 1673 rsp->SecurityBufferOffset = cpu_to_le16(72); 1687 1674 rsp->SecurityBufferLength = 0; 1688 - inc_rfc1001_len(work->response_buf, 9); 1689 1675 1690 1676 ksmbd_conn_lock(conn); 1691 1677 if (!req->hdr.SessionId) { ··· 1820 1808 goto out_err; 1821 1809 rsp->hdr.Status = 1822 1810 STATUS_MORE_PROCESSING_REQUIRED; 1823 - /* 1824 - * Note: here total size -1 is done as an 1825 - * adjustment for 0 size blob 1826 - */ 1827 - inc_rfc1001_len(work->response_buf, 1828 - le16_to_cpu(rsp->SecurityBufferLength) - 1); 1829 - 1830 1811 } else if (negblob->MessageType == NtLmAuthenticate) { 1831 1812 rc = ntlm_authenticate(work, req, rsp); 1832 1813 if (rc) ··· 1904 1899 ksmbd_conn_set_need_negotiate(conn); 1905 1900 } 1906 1901 } 1902 + smb2_set_err_rsp(work); 1903 + } else { 1904 + unsigned int iov_len; 1905 + 1906 + if (rsp->SecurityBufferLength) 1907 + iov_len = offsetof(struct smb2_sess_setup_rsp, Buffer) + 1908 + le16_to_cpu(rsp->SecurityBufferLength); 1909 + else 1910 + iov_len = sizeof(struct smb2_sess_setup_rsp); 1911 + rc = ksmbd_iov_pin_rsp(work, rsp, iov_len); 1912 + if (rc) 1913 + rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; 1907 1914 } 1908 1915 1909 1916 ksmbd_conn_unlock(conn); ··· 1994 1977 status.tree_conn->posix_extensions = true; 1995 1978 1996 1979 rsp->StructureSize = cpu_to_le16(16); 1997 - inc_rfc1001_len(work->response_buf, 16); 1998 1980 out_err1: 1999 1981 rsp->Capabilities = 0; 2000 1982 rsp->Reserved = 0; 2001 1983 /* default manual caching */ 2002 1984 rsp->ShareFlags = SMB2_SHAREFLAG_MANUAL_CACHING; 1985 + 1986 + rc = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_tree_connect_rsp)); 1987 + if (rc) 1988 + status.ret = KSMBD_TREE_CONN_STATUS_NOMEM; 2003 1989 2004 1990 if (!IS_ERR(treename)) 2005 1991 kfree(treename); ··· 2116 2096 struct smb2_tree_disconnect_req *req; 2117 2097 struct ksmbd_session *sess = work->sess; 2118 2098 struct ksmbd_tree_connect *tcon = work->tcon; 2099 + int err; 2119 2100 2120 2101 WORK_BUFFERS(work, req, rsp); 2121 2102 2122 - rsp->StructureSize = cpu_to_le16(4); 2123 - inc_rfc1001_len(work->response_buf, 4); 2124 - 2125 2103 ksmbd_debug(SMB, "request\n"); 2104 + 2105 + rsp->StructureSize = cpu_to_le16(4); 2106 + err = ksmbd_iov_pin_rsp(work, rsp, 2107 + sizeof(struct smb2_tree_disconnect_rsp)); 2108 + if (err) { 2109 + rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; 2110 + smb2_set_err_rsp(work); 2111 + return err; 2112 + } 2126 2113 2127 2114 if (!tcon || test_and_set_bit(TREE_CONN_EXPIRE, &tcon->status)) { 2128 2115 ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); 2129 2116 2130 2117 rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; 2131 2118 smb2_set_err_rsp(work); 2132 - return 0; 2119 + return -ENOENT; 2133 2120 } 2134 2121 2135 2122 ksmbd_close_tree_conn_fds(work); ··· 2158 2131 struct smb2_logoff_rsp *rsp; 2159 2132 struct ksmbd_session *sess; 2160 2133 u64 sess_id; 2134 + int err; 2161 2135 2162 2136 WORK_BUFFERS(work, req, rsp); 2137 + 2138 + ksmbd_debug(SMB, "request\n"); 2163 2139 2164 2140 sess_id = le64_to_cpu(req->hdr.SessionId); 2165 2141 2166 2142 rsp->StructureSize = cpu_to_le16(4); 2167 - inc_rfc1001_len(work->response_buf, 4); 2168 - 2169 - ksmbd_debug(SMB, "request\n"); 2143 + err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_logoff_rsp)); 2144 + if (err) { 2145 + rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; 2146 + smb2_set_err_rsp(work); 2147 + return err; 2148 + } 2170 2149 2171 2150 ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_RECONNECT); 2172 2151 ksmbd_close_session_fds(work); ··· 2187 2154 ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); 2188 2155 rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; 2189 2156 smb2_set_err_rsp(work); 2190 - return 0; 2157 + return -ENOENT; 2191 2158 } 2192 2159 2193 2160 ksmbd_destroy_file_table(&sess->file_table); ··· 2248 2215 rsp->CreateContextsOffset = 0; 2249 2216 rsp->CreateContextsLength = 0; 2250 2217 2251 - inc_rfc1001_len(work->response_buf, 88); /* StructureSize - 1*/ 2218 + err = ksmbd_iov_pin_rsp(work, rsp, offsetof(struct smb2_create_rsp, Buffer)); 2219 + if (err) 2220 + goto out; 2221 + 2252 2222 kfree(name); 2253 2223 return 0; 2254 2224 ··· 2633 2597 u64 time; 2634 2598 umode_t posix_mode = 0; 2635 2599 __le32 daccess, maximal_access = 0; 2600 + int iov_len = 0; 2636 2601 2637 2602 WORK_BUFFERS(work, req, rsp); 2638 2603 ··· 3285 3248 3286 3249 rsp->CreateContextsOffset = 0; 3287 3250 rsp->CreateContextsLength = 0; 3288 - inc_rfc1001_len(work->response_buf, 88); /* StructureSize - 1*/ 3251 + iov_len = offsetof(struct smb2_create_rsp, Buffer); 3289 3252 3290 3253 /* If lease is request send lease context response */ 3291 3254 if (opinfo && opinfo->is_lease) { ··· 3300 3263 create_lease_buf(rsp->Buffer, opinfo->o_lease); 3301 3264 le32_add_cpu(&rsp->CreateContextsLength, 3302 3265 conn->vals->create_lease_size); 3303 - inc_rfc1001_len(work->response_buf, 3304 - conn->vals->create_lease_size); 3266 + iov_len += conn->vals->create_lease_size; 3305 3267 next_ptr = &lease_ccontext->Next; 3306 3268 next_off = conn->vals->create_lease_size; 3307 3269 } ··· 3320 3284 le32_to_cpu(maximal_access)); 3321 3285 le32_add_cpu(&rsp->CreateContextsLength, 3322 3286 conn->vals->create_mxac_size); 3323 - inc_rfc1001_len(work->response_buf, 3324 - conn->vals->create_mxac_size); 3287 + iov_len += conn->vals->create_mxac_size; 3325 3288 if (next_ptr) 3326 3289 *next_ptr = cpu_to_le32(next_off); 3327 3290 next_ptr = &mxac_ccontext->Next; ··· 3338 3303 stat.ino, tcon->id); 3339 3304 le32_add_cpu(&rsp->CreateContextsLength, 3340 3305 conn->vals->create_disk_id_size); 3341 - inc_rfc1001_len(work->response_buf, 3342 - conn->vals->create_disk_id_size); 3306 + iov_len += conn->vals->create_disk_id_size; 3343 3307 if (next_ptr) 3344 3308 *next_ptr = cpu_to_le32(next_off); 3345 3309 next_ptr = &disk_id_ccontext->Next; ··· 3352 3318 fp); 3353 3319 le32_add_cpu(&rsp->CreateContextsLength, 3354 3320 conn->vals->create_posix_size); 3355 - inc_rfc1001_len(work->response_buf, 3356 - conn->vals->create_posix_size); 3321 + iov_len += conn->vals->create_posix_size; 3357 3322 if (next_ptr) 3358 3323 *next_ptr = cpu_to_le32(next_off); 3359 3324 } ··· 3370 3337 } 3371 3338 ksmbd_revert_fsids(work); 3372 3339 err_out1: 3373 - 3340 + if (!rc) 3341 + rc = ksmbd_iov_pin_rsp(work, (void *)rsp, iov_len); 3374 3342 if (rc) { 3375 3343 if (rc == -EINVAL) 3376 3344 rsp->hdr.Status = STATUS_INVALID_PARAMETER; ··· 4097 4063 rsp->OutputBufferOffset = cpu_to_le16(0); 4098 4064 rsp->OutputBufferLength = cpu_to_le32(0); 4099 4065 rsp->Buffer[0] = 0; 4100 - inc_rfc1001_len(work->response_buf, 9); 4066 + rc = ksmbd_iov_pin_rsp(work, (void *)rsp, 4067 + sizeof(struct smb2_query_directory_rsp)); 4068 + if (rc) 4069 + goto err_out; 4101 4070 } else { 4102 4071 no_buf_len: 4103 4072 ((struct file_directory_info *) ··· 4112 4075 rsp->StructureSize = cpu_to_le16(9); 4113 4076 rsp->OutputBufferOffset = cpu_to_le16(72); 4114 4077 rsp->OutputBufferLength = cpu_to_le32(d_info.data_count); 4115 - inc_rfc1001_len(work->response_buf, 8 + d_info.data_count); 4078 + rc = ksmbd_iov_pin_rsp(work, (void *)rsp, 4079 + offsetof(struct smb2_query_directory_rsp, Buffer) + 4080 + d_info.data_count); 4081 + if (rc) 4082 + goto err_out; 4116 4083 } 4117 4084 4118 4085 kfree(srch_ptr); ··· 4157 4116 * @reqOutputBufferLength: max buffer length expected in command response 4158 4117 * @rsp: query info response buffer contains output buffer length 4159 4118 * @rsp_org: base response buffer pointer in case of chained response 4160 - * @infoclass_size: query info class response buffer size 4161 4119 * 4162 4120 * Return: 0 on success, otherwise error 4163 4121 */ 4164 4122 static int buffer_check_err(int reqOutputBufferLength, 4165 4123 struct smb2_query_info_rsp *rsp, 4166 - void *rsp_org, int infoclass_size) 4124 + void *rsp_org) 4167 4125 { 4168 4126 if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) { 4169 - if (reqOutputBufferLength < infoclass_size) { 4170 - pr_err("Invalid Buffer Size Requested\n"); 4171 - rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH; 4172 - *(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr)); 4173 - return -EINVAL; 4174 - } 4175 - 4176 - ksmbd_debug(SMB, "Buffer Overflow\n"); 4177 - rsp->hdr.Status = STATUS_BUFFER_OVERFLOW; 4178 - *(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr) + 4179 - reqOutputBufferLength); 4180 - rsp->OutputBufferLength = cpu_to_le32(reqOutputBufferLength); 4127 + pr_err("Invalid Buffer Size Requested\n"); 4128 + rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH; 4129 + *(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr)); 4130 + return -EINVAL; 4181 4131 } 4182 4132 return 0; 4183 4133 } ··· 4187 4155 sinfo->Directory = 0; 4188 4156 rsp->OutputBufferLength = 4189 4157 cpu_to_le32(sizeof(struct smb2_file_standard_info)); 4190 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_standard_info)); 4191 4158 } 4192 4159 4193 4160 static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num, ··· 4200 4169 file_info->IndexNumber = cpu_to_le64(num | (1ULL << 63)); 4201 4170 rsp->OutputBufferLength = 4202 4171 cpu_to_le32(sizeof(struct smb2_file_internal_info)); 4203 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_internal_info)); 4204 4172 } 4205 4173 4206 4174 static int smb2_get_info_file_pipe(struct ksmbd_session *sess, ··· 4225 4195 case FILE_STANDARD_INFORMATION: 4226 4196 get_standard_info_pipe(rsp, rsp_org); 4227 4197 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), 4228 - rsp, rsp_org, 4229 - FILE_STANDARD_INFORMATION_SIZE); 4198 + rsp, rsp_org); 4230 4199 break; 4231 4200 case FILE_INTERNAL_INFORMATION: 4232 4201 get_internal_info_pipe(rsp, id, rsp_org); 4233 4202 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), 4234 - rsp, rsp_org, 4235 - FILE_INTERNAL_INFORMATION_SIZE); 4203 + rsp, rsp_org); 4236 4204 break; 4237 4205 default: 4238 4206 ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n", ··· 4336 4308 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) 4337 4309 name_len -= XATTR_USER_PREFIX_LEN; 4338 4310 4339 - ptr = (char *)(&eainfo->name + name_len + 1); 4311 + ptr = eainfo->name + name_len + 1; 4340 4312 buf_free_len -= (offsetof(struct smb2_ea_info, name) + 4341 4313 name_len + 1); 4342 4314 /* bailout if xattr can't fit in buf_free_len */ ··· 4398 4370 if (rsp_data_cnt == 0) 4399 4371 rsp->hdr.Status = STATUS_NO_EAS_ON_FILE; 4400 4372 rsp->OutputBufferLength = cpu_to_le32(rsp_data_cnt); 4401 - inc_rfc1001_len(rsp_org, rsp_data_cnt); 4402 4373 out: 4403 4374 kvfree(xattr_list); 4404 4375 return rc; ··· 4412 4385 file_info->AccessFlags = fp->daccess; 4413 4386 rsp->OutputBufferLength = 4414 4387 cpu_to_le32(sizeof(struct smb2_file_access_info)); 4415 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_access_info)); 4416 4388 } 4417 4389 4418 4390 static int get_file_basic_info(struct smb2_query_info_rsp *rsp, ··· 4441 4415 basic_info->Pad1 = 0; 4442 4416 rsp->OutputBufferLength = 4443 4417 cpu_to_le32(sizeof(struct smb2_file_basic_info)); 4444 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_basic_info)); 4445 4418 return 0; 4446 4419 } 4447 4420 ··· 4465 4440 sinfo->Directory = S_ISDIR(stat.mode) ? 1 : 0; 4466 4441 rsp->OutputBufferLength = 4467 4442 cpu_to_le32(sizeof(struct smb2_file_standard_info)); 4468 - inc_rfc1001_len(rsp_org, 4469 - sizeof(struct smb2_file_standard_info)); 4470 4443 } 4471 4444 4472 4445 static void get_file_alignment_info(struct smb2_query_info_rsp *rsp, ··· 4476 4453 file_info->AlignmentRequirement = 0; 4477 4454 rsp->OutputBufferLength = 4478 4455 cpu_to_le32(sizeof(struct smb2_file_alignment_info)); 4479 - inc_rfc1001_len(rsp_org, 4480 - sizeof(struct smb2_file_alignment_info)); 4481 4456 } 4482 4457 4483 4458 static int get_file_all_info(struct ksmbd_work *work, ··· 4539 4518 rsp->OutputBufferLength = 4540 4519 cpu_to_le32(sizeof(struct smb2_file_all_info) + conv_len - 1); 4541 4520 kfree(filename); 4542 - inc_rfc1001_len(rsp_org, le32_to_cpu(rsp->OutputBufferLength)); 4543 4521 return 0; 4544 4522 } 4545 4523 ··· 4561 4541 file_info->FileNameLength = cpu_to_le32(conv_len); 4562 4542 rsp->OutputBufferLength = 4563 4543 cpu_to_le32(sizeof(struct smb2_file_alt_name_info) + conv_len); 4564 - inc_rfc1001_len(rsp_org, le32_to_cpu(rsp->OutputBufferLength)); 4565 4544 } 4566 4545 4567 4546 static void get_file_stream_info(struct ksmbd_work *work, ··· 4660 4641 kvfree(xattr_list); 4661 4642 4662 4643 rsp->OutputBufferLength = cpu_to_le32(nbytes); 4663 - inc_rfc1001_len(rsp_org, nbytes); 4664 4644 } 4665 4645 4666 4646 static void get_file_internal_info(struct smb2_query_info_rsp *rsp, ··· 4674 4656 file_info->IndexNumber = cpu_to_le64(stat.ino); 4675 4657 rsp->OutputBufferLength = 4676 4658 cpu_to_le32(sizeof(struct smb2_file_internal_info)); 4677 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_internal_info)); 4678 4659 } 4679 4660 4680 4661 static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, ··· 4709 4692 file_info->Reserved = cpu_to_le32(0); 4710 4693 rsp->OutputBufferLength = 4711 4694 cpu_to_le32(sizeof(struct smb2_file_ntwrk_info)); 4712 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_ntwrk_info)); 4713 4695 return 0; 4714 4696 } 4715 4697 ··· 4720 4704 file_info->EASize = 0; 4721 4705 rsp->OutputBufferLength = 4722 4706 cpu_to_le32(sizeof(struct smb2_file_ea_info)); 4723 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_ea_info)); 4724 4707 } 4725 4708 4726 4709 static void get_file_position_info(struct smb2_query_info_rsp *rsp, ··· 4731 4716 file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos); 4732 4717 rsp->OutputBufferLength = 4733 4718 cpu_to_le32(sizeof(struct smb2_file_pos_info)); 4734 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_pos_info)); 4735 4719 } 4736 4720 4737 4721 static void get_file_mode_info(struct smb2_query_info_rsp *rsp, ··· 4742 4728 file_info->Mode = fp->coption & FILE_MODE_INFO_MASK; 4743 4729 rsp->OutputBufferLength = 4744 4730 cpu_to_le32(sizeof(struct smb2_file_mode_info)); 4745 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_mode_info)); 4746 4731 } 4747 4732 4748 4733 static void get_file_compression_info(struct smb2_query_info_rsp *rsp, ··· 4763 4750 4764 4751 rsp->OutputBufferLength = 4765 4752 cpu_to_le32(sizeof(struct smb2_file_comp_info)); 4766 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_comp_info)); 4767 4753 } 4768 4754 4769 4755 static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp, ··· 4781 4769 file_info->ReparseTag = 0; 4782 4770 rsp->OutputBufferLength = 4783 4771 cpu_to_le32(sizeof(struct smb2_file_attr_tag_info)); 4784 - inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_attr_tag_info)); 4785 4772 return 0; 4786 4773 } 4787 4774 4788 - static int find_file_posix_info(struct smb2_query_info_rsp *rsp, 4775 + static void find_file_posix_info(struct smb2_query_info_rsp *rsp, 4789 4776 struct ksmbd_file *fp, void *rsp_org) 4790 4777 { 4791 4778 struct smb311_posix_qinfo *file_info; ··· 4822 4811 SIDUNIX_GROUP, (struct smb_sid *)&file_info->Sids[16]); 4823 4812 4824 4813 rsp->OutputBufferLength = cpu_to_le32(out_buf_len); 4825 - inc_rfc1001_len(rsp_org, out_buf_len); 4826 - return out_buf_len; 4827 4814 } 4828 4815 4829 4816 static int smb2_get_info_file(struct ksmbd_work *work, ··· 4831 4822 struct ksmbd_file *fp; 4832 4823 int fileinfoclass = 0; 4833 4824 int rc = 0; 4834 - int file_infoclass_size; 4835 4825 unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; 4836 4826 4837 4827 if (test_share_config_flag(work->tcon->share_conf, ··· 4863 4855 switch (fileinfoclass) { 4864 4856 case FILE_ACCESS_INFORMATION: 4865 4857 get_file_access_info(rsp, fp, work->response_buf); 4866 - file_infoclass_size = FILE_ACCESS_INFORMATION_SIZE; 4867 4858 break; 4868 4859 4869 4860 case FILE_BASIC_INFORMATION: 4870 4861 rc = get_file_basic_info(rsp, fp, work->response_buf); 4871 - file_infoclass_size = FILE_BASIC_INFORMATION_SIZE; 4872 4862 break; 4873 4863 4874 4864 case FILE_STANDARD_INFORMATION: 4875 4865 get_file_standard_info(rsp, fp, work->response_buf); 4876 - file_infoclass_size = FILE_STANDARD_INFORMATION_SIZE; 4877 4866 break; 4878 4867 4879 4868 case FILE_ALIGNMENT_INFORMATION: 4880 4869 get_file_alignment_info(rsp, work->response_buf); 4881 - file_infoclass_size = FILE_ALIGNMENT_INFORMATION_SIZE; 4882 4870 break; 4883 4871 4884 4872 case FILE_ALL_INFORMATION: 4885 4873 rc = get_file_all_info(work, rsp, fp, work->response_buf); 4886 - file_infoclass_size = FILE_ALL_INFORMATION_SIZE; 4887 4874 break; 4888 4875 4889 4876 case FILE_ALTERNATE_NAME_INFORMATION: 4890 4877 get_file_alternate_info(work, rsp, fp, work->response_buf); 4891 - file_infoclass_size = FILE_ALTERNATE_NAME_INFORMATION_SIZE; 4892 4878 break; 4893 4879 4894 4880 case FILE_STREAM_INFORMATION: 4895 4881 get_file_stream_info(work, rsp, fp, work->response_buf); 4896 - file_infoclass_size = FILE_STREAM_INFORMATION_SIZE; 4897 4882 break; 4898 4883 4899 4884 case FILE_INTERNAL_INFORMATION: 4900 4885 get_file_internal_info(rsp, fp, work->response_buf); 4901 - file_infoclass_size = FILE_INTERNAL_INFORMATION_SIZE; 4902 4886 break; 4903 4887 4904 4888 case FILE_NETWORK_OPEN_INFORMATION: 4905 4889 rc = get_file_network_open_info(rsp, fp, work->response_buf); 4906 - file_infoclass_size = FILE_NETWORK_OPEN_INFORMATION_SIZE; 4907 4890 break; 4908 4891 4909 4892 case FILE_EA_INFORMATION: 4910 4893 get_file_ea_info(rsp, work->response_buf); 4911 - file_infoclass_size = FILE_EA_INFORMATION_SIZE; 4912 4894 break; 4913 4895 4914 4896 case FILE_FULL_EA_INFORMATION: 4915 4897 rc = smb2_get_ea(work, fp, req, rsp, work->response_buf); 4916 - file_infoclass_size = FILE_FULL_EA_INFORMATION_SIZE; 4917 4898 break; 4918 4899 4919 4900 case FILE_POSITION_INFORMATION: 4920 4901 get_file_position_info(rsp, fp, work->response_buf); 4921 - file_infoclass_size = FILE_POSITION_INFORMATION_SIZE; 4922 4902 break; 4923 4903 4924 4904 case FILE_MODE_INFORMATION: 4925 4905 get_file_mode_info(rsp, fp, work->response_buf); 4926 - file_infoclass_size = FILE_MODE_INFORMATION_SIZE; 4927 4906 break; 4928 4907 4929 4908 case FILE_COMPRESSION_INFORMATION: 4930 4909 get_file_compression_info(rsp, fp, work->response_buf); 4931 - file_infoclass_size = FILE_COMPRESSION_INFORMATION_SIZE; 4932 4910 break; 4933 4911 4934 4912 case FILE_ATTRIBUTE_TAG_INFORMATION: 4935 4913 rc = get_file_attribute_tag_info(rsp, fp, work->response_buf); 4936 - file_infoclass_size = FILE_ATTRIBUTE_TAG_INFORMATION_SIZE; 4937 4914 break; 4938 4915 case SMB_FIND_FILE_POSIX_INFO: 4939 4916 if (!work->tcon->posix_extensions) { 4940 4917 pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); 4941 4918 rc = -EOPNOTSUPP; 4942 4919 } else { 4943 - file_infoclass_size = find_file_posix_info(rsp, fp, 4944 - work->response_buf); 4920 + find_file_posix_info(rsp, fp, work->response_buf); 4945 4921 } 4946 4922 break; 4947 4923 default: ··· 4935 4943 } 4936 4944 if (!rc) 4937 4945 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), 4938 - rsp, work->response_buf, 4939 - file_infoclass_size); 4946 + rsp, work->response_buf); 4940 4947 ksmbd_fd_put(work, fp); 4941 4948 return rc; 4942 4949 } ··· 4951 4960 struct kstatfs stfs; 4952 4961 struct path path; 4953 4962 int rc = 0, len; 4954 - int fs_infoclass_size = 0; 4955 4963 4956 4964 if (!share->path) 4957 4965 return -EIO; ··· 4980 4990 info->DeviceType = cpu_to_le32(stfs.f_type); 4981 4991 info->DeviceCharacteristics = cpu_to_le32(0x00000020); 4982 4992 rsp->OutputBufferLength = cpu_to_le32(8); 4983 - inc_rfc1001_len(work->response_buf, 8); 4984 - fs_infoclass_size = FS_DEVICE_INFORMATION_SIZE; 4985 4993 break; 4986 4994 } 4987 4995 case FS_ATTRIBUTE_INFORMATION: ··· 5008 5020 info->FileSystemNameLen = cpu_to_le32(len); 5009 5021 sz = sizeof(struct filesystem_attribute_info) - 2 + len; 5010 5022 rsp->OutputBufferLength = cpu_to_le32(sz); 5011 - inc_rfc1001_len(work->response_buf, sz); 5012 - fs_infoclass_size = FS_ATTRIBUTE_INFORMATION_SIZE; 5013 5023 break; 5014 5024 } 5015 5025 case FS_VOLUME_INFORMATION: ··· 5034 5048 info->Reserved = 0; 5035 5049 sz = sizeof(struct filesystem_vol_info) - 2 + len; 5036 5050 rsp->OutputBufferLength = cpu_to_le32(sz); 5037 - inc_rfc1001_len(work->response_buf, sz); 5038 - fs_infoclass_size = FS_VOLUME_INFORMATION_SIZE; 5039 5051 break; 5040 5052 } 5041 5053 case FS_SIZE_INFORMATION: ··· 5046 5062 info->SectorsPerAllocationUnit = cpu_to_le32(1); 5047 5063 info->BytesPerSector = cpu_to_le32(stfs.f_bsize); 5048 5064 rsp->OutputBufferLength = cpu_to_le32(24); 5049 - inc_rfc1001_len(work->response_buf, 24); 5050 - fs_infoclass_size = FS_SIZE_INFORMATION_SIZE; 5051 5065 break; 5052 5066 } 5053 5067 case FS_FULL_SIZE_INFORMATION: ··· 5061 5079 info->SectorsPerAllocationUnit = cpu_to_le32(1); 5062 5080 info->BytesPerSector = cpu_to_le32(stfs.f_bsize); 5063 5081 rsp->OutputBufferLength = cpu_to_le32(32); 5064 - inc_rfc1001_len(work->response_buf, 32); 5065 - fs_infoclass_size = FS_FULL_SIZE_INFORMATION_SIZE; 5066 5082 break; 5067 5083 } 5068 5084 case FS_OBJECT_ID_INFORMATION: ··· 5080 5100 info->extended_info.rel_date = 0; 5081 5101 memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0")); 5082 5102 rsp->OutputBufferLength = cpu_to_le32(64); 5083 - inc_rfc1001_len(work->response_buf, 64); 5084 - fs_infoclass_size = FS_OBJECT_ID_INFORMATION_SIZE; 5085 5103 break; 5086 5104 } 5087 5105 case FS_SECTOR_SIZE_INFORMATION: ··· 5101 5123 info->ByteOffsetForSectorAlignment = 0; 5102 5124 info->ByteOffsetForPartitionAlignment = 0; 5103 5125 rsp->OutputBufferLength = cpu_to_le32(28); 5104 - inc_rfc1001_len(work->response_buf, 28); 5105 - fs_infoclass_size = FS_SECTOR_SIZE_INFORMATION_SIZE; 5106 5126 break; 5107 5127 } 5108 5128 case FS_CONTROL_INFORMATION: ··· 5121 5145 info->DefaultQuotaLimit = cpu_to_le64(SMB2_NO_FID); 5122 5146 info->Padding = 0; 5123 5147 rsp->OutputBufferLength = cpu_to_le32(48); 5124 - inc_rfc1001_len(work->response_buf, 48); 5125 - fs_infoclass_size = FS_CONTROL_INFORMATION_SIZE; 5126 5148 break; 5127 5149 } 5128 5150 case FS_POSIX_INFORMATION: ··· 5140 5166 info->TotalFileNodes = cpu_to_le64(stfs.f_files); 5141 5167 info->FreeFileNodes = cpu_to_le64(stfs.f_ffree); 5142 5168 rsp->OutputBufferLength = cpu_to_le32(56); 5143 - inc_rfc1001_len(work->response_buf, 56); 5144 - fs_infoclass_size = FS_POSIX_INFORMATION_SIZE; 5145 5169 } 5146 5170 break; 5147 5171 } ··· 5148 5176 return -EOPNOTSUPP; 5149 5177 } 5150 5178 rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), 5151 - rsp, work->response_buf, 5152 - fs_infoclass_size); 5179 + rsp, work->response_buf); 5153 5180 path_put(&path); 5154 5181 return rc; 5155 5182 } ··· 5182 5211 5183 5212 secdesclen = sizeof(struct smb_ntsd); 5184 5213 rsp->OutputBufferLength = cpu_to_le32(secdesclen); 5185 - inc_rfc1001_len(work->response_buf, secdesclen); 5186 5214 5187 5215 return 0; 5188 5216 } ··· 5226 5256 return rc; 5227 5257 5228 5258 rsp->OutputBufferLength = cpu_to_le32(secdesclen); 5229 - inc_rfc1001_len(work->response_buf, secdesclen); 5230 5259 return 0; 5231 5260 } 5232 5261 ··· 5264 5295 rc = -EOPNOTSUPP; 5265 5296 } 5266 5297 5298 + if (!rc) { 5299 + rsp->StructureSize = cpu_to_le16(9); 5300 + rsp->OutputBufferOffset = cpu_to_le16(72); 5301 + rc = ksmbd_iov_pin_rsp(work, (void *)rsp, 5302 + offsetof(struct smb2_query_info_rsp, Buffer) + 5303 + le32_to_cpu(rsp->OutputBufferLength)); 5304 + } 5305 + 5267 5306 if (rc < 0) { 5268 5307 if (rc == -EACCES) 5269 5308 rsp->hdr.Status = STATUS_ACCESS_DENIED; ··· 5279 5302 rsp->hdr.Status = STATUS_FILE_CLOSED; 5280 5303 else if (rc == -EIO) 5281 5304 rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR; 5305 + else if (rc == -ENOMEM) 5306 + rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; 5282 5307 else if (rc == -EOPNOTSUPP || rsp->hdr.Status == 0) 5283 5308 rsp->hdr.Status = STATUS_INVALID_INFO_CLASS; 5284 5309 smb2_set_err_rsp(work); ··· 5289 5310 rc); 5290 5311 return rc; 5291 5312 } 5292 - rsp->StructureSize = cpu_to_le16(9); 5293 - rsp->OutputBufferOffset = cpu_to_le16(72); 5294 - inc_rfc1001_len(work->response_buf, 8); 5295 5313 return 0; 5296 5314 } 5297 5315 ··· 5319 5343 rsp->AllocationSize = 0; 5320 5344 rsp->EndOfFile = 0; 5321 5345 rsp->Attributes = 0; 5322 - inc_rfc1001_len(work->response_buf, 60); 5323 - return 0; 5346 + 5347 + return ksmbd_iov_pin_rsp(work, (void *)rsp, 5348 + sizeof(struct smb2_close_rsp)); 5324 5349 } 5325 5350 5326 5351 /** ··· 5426 5449 5427 5450 err = ksmbd_close_fd(work, volatile_id); 5428 5451 out: 5452 + if (!err) 5453 + err = ksmbd_iov_pin_rsp(work, (void *)rsp, 5454 + sizeof(struct smb2_close_rsp)); 5455 + 5429 5456 if (err) { 5430 5457 if (rsp->hdr.Status == 0) 5431 5458 rsp->hdr.Status = STATUS_FILE_CLOSED; 5432 5459 smb2_set_err_rsp(work); 5433 - } else { 5434 - inc_rfc1001_len(work->response_buf, 60); 5435 5460 } 5436 5461 5437 - return 0; 5462 + return err; 5438 5463 } 5439 5464 5440 5465 /** ··· 5454 5475 5455 5476 rsp->StructureSize = cpu_to_le16(4); 5456 5477 rsp->Reserved = 0; 5457 - inc_rfc1001_len(work->response_buf, 4); 5458 - return 0; 5478 + return ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_echo_rsp)); 5459 5479 } 5460 5480 5461 5481 static int smb2_rename(struct ksmbd_work *work, ··· 6046 6068 goto err_out; 6047 6069 6048 6070 rsp->StructureSize = cpu_to_le16(2); 6049 - inc_rfc1001_len(work->response_buf, 2); 6071 + rc = ksmbd_iov_pin_rsp(work, (void *)rsp, 6072 + sizeof(struct smb2_set_info_rsp)); 6073 + if (rc) 6074 + goto err_out; 6050 6075 ksmbd_fd_put(work, fp); 6051 6076 return 0; 6052 6077 ··· 6096 6115 6097 6116 id = req->VolatileFileId; 6098 6117 6099 - inc_rfc1001_len(work->response_buf, 16); 6100 6118 rpc_resp = ksmbd_rpc_read(work->sess, id); 6101 6119 if (rpc_resp) { 6120 + void *aux_payload_buf; 6121 + 6102 6122 if (rpc_resp->flags != KSMBD_RPC_OK) { 6103 6123 err = -EINVAL; 6104 6124 goto out; 6105 6125 } 6106 6126 6107 - work->aux_payload_buf = 6127 + aux_payload_buf = 6108 6128 kvmalloc(rpc_resp->payload_sz, GFP_KERNEL); 6109 - if (!work->aux_payload_buf) { 6129 + if (!aux_payload_buf) { 6110 6130 err = -ENOMEM; 6111 6131 goto out; 6112 6132 } 6113 6133 6114 - memcpy(work->aux_payload_buf, rpc_resp->payload, 6115 - rpc_resp->payload_sz); 6134 + memcpy(aux_payload_buf, rpc_resp->payload, rpc_resp->payload_sz); 6116 6135 6117 6136 nbytes = rpc_resp->payload_sz; 6118 - work->resp_hdr_sz = get_rfc1002_len(work->response_buf) + 4; 6119 - work->aux_payload_sz = nbytes; 6120 6137 kvfree(rpc_resp); 6138 + err = ksmbd_iov_pin_rsp_read(work, (void *)rsp, 6139 + offsetof(struct smb2_read_rsp, Buffer), 6140 + aux_payload_buf, nbytes); 6141 + if (err) 6142 + goto out; 6143 + } else { 6144 + err = ksmbd_iov_pin_rsp(work, (void *)rsp, 6145 + offsetof(struct smb2_read_rsp, Buffer)); 6146 + if (err) 6147 + goto out; 6121 6148 } 6122 6149 6123 6150 rsp->StructureSize = cpu_to_le16(17); ··· 6134 6145 rsp->DataLength = cpu_to_le32(nbytes); 6135 6146 rsp->DataRemaining = 0; 6136 6147 rsp->Flags = 0; 6137 - inc_rfc1001_len(work->response_buf, nbytes); 6138 6148 return 0; 6139 6149 6140 6150 out: ··· 6207 6219 int err = 0; 6208 6220 bool is_rdma_channel = false; 6209 6221 unsigned int max_read_size = conn->vals->max_read_size; 6210 - 6211 - WORK_BUFFERS(work, req, rsp); 6212 - if (work->next_smb2_rcv_hdr_off) { 6213 - work->send_no_response = 1; 6214 - err = -EOPNOTSUPP; 6215 - goto out; 6216 - } 6222 + unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; 6223 + void *aux_payload_buf; 6217 6224 6218 6225 if (test_share_config_flag(work->tcon->share_conf, 6219 6226 KSMBD_SHARE_FLAG_PIPE)) { 6220 6227 ksmbd_debug(SMB, "IPC pipe read request\n"); 6221 6228 return smb2_read_pipe(work); 6229 + } 6230 + 6231 + if (work->next_smb2_rcv_hdr_off) { 6232 + req = ksmbd_req_buf_next(work); 6233 + rsp = ksmbd_resp_buf_next(work); 6234 + if (!has_file_id(req->VolatileFileId)) { 6235 + ksmbd_debug(SMB, "Compound request set FID = %llu\n", 6236 + work->compound_fid); 6237 + id = work->compound_fid; 6238 + pid = work->compound_pfid; 6239 + } 6240 + } else { 6241 + req = smb2_get_msg(work->request_buf); 6242 + rsp = smb2_get_msg(work->response_buf); 6243 + } 6244 + 6245 + if (!has_file_id(id)) { 6246 + id = req->VolatileFileId; 6247 + pid = req->PersistentFileId; 6222 6248 } 6223 6249 6224 6250 if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE || ··· 6257 6255 goto out; 6258 6256 } 6259 6257 6260 - fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId); 6258 + fp = ksmbd_lookup_fd_slow(work, id, pid); 6261 6259 if (!fp) { 6262 6260 err = -ENOENT; 6263 6261 goto out; ··· 6283 6281 ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n", 6284 6282 fp->filp, offset, length); 6285 6283 6286 - work->aux_payload_buf = kvzalloc(length, GFP_KERNEL); 6287 - if (!work->aux_payload_buf) { 6284 + aux_payload_buf = kvzalloc(length, GFP_KERNEL); 6285 + if (!aux_payload_buf) { 6288 6286 err = -ENOMEM; 6289 6287 goto out; 6290 6288 } 6291 6289 6292 - nbytes = ksmbd_vfs_read(work, fp, length, &offset); 6290 + nbytes = ksmbd_vfs_read(work, fp, length, &offset, aux_payload_buf); 6293 6291 if (nbytes < 0) { 6294 6292 err = nbytes; 6295 6293 goto out; 6296 6294 } 6297 6295 6298 6296 if ((nbytes == 0 && length != 0) || nbytes < mincount) { 6299 - kvfree(work->aux_payload_buf); 6300 - work->aux_payload_buf = NULL; 6297 + kvfree(aux_payload_buf); 6301 6298 rsp->hdr.Status = STATUS_END_OF_FILE; 6302 6299 smb2_set_err_rsp(work); 6303 6300 ksmbd_fd_put(work, fp); ··· 6309 6308 if (is_rdma_channel == true) { 6310 6309 /* write data to the client using rdma channel */ 6311 6310 remain_bytes = smb2_read_rdma_channel(work, req, 6312 - work->aux_payload_buf, 6311 + aux_payload_buf, 6313 6312 nbytes); 6314 - kvfree(work->aux_payload_buf); 6315 - work->aux_payload_buf = NULL; 6313 + kvfree(aux_payload_buf); 6316 6314 6317 6315 nbytes = 0; 6318 6316 if (remain_bytes < 0) { ··· 6326 6326 rsp->DataLength = cpu_to_le32(nbytes); 6327 6327 rsp->DataRemaining = cpu_to_le32(remain_bytes); 6328 6328 rsp->Flags = 0; 6329 - inc_rfc1001_len(work->response_buf, 16); 6330 - work->resp_hdr_sz = get_rfc1002_len(work->response_buf) + 4; 6331 - work->aux_payload_sz = nbytes; 6332 - inc_rfc1001_len(work->response_buf, nbytes); 6329 + err = ksmbd_iov_pin_rsp_read(work, (void *)rsp, 6330 + offsetof(struct smb2_read_rsp, Buffer), 6331 + aux_payload_buf, nbytes); 6332 + if (err) 6333 + goto out; 6333 6334 ksmbd_fd_put(work, fp); 6334 6335 return 0; 6335 6336 ··· 6413 6412 rsp->DataLength = cpu_to_le32(length); 6414 6413 rsp->DataRemaining = 0; 6415 6414 rsp->Reserved2 = 0; 6416 - inc_rfc1001_len(work->response_buf, 16); 6417 - return 0; 6415 + err = ksmbd_iov_pin_rsp(work, (void *)rsp, 6416 + offsetof(struct smb2_write_rsp, Buffer)); 6418 6417 out: 6419 6418 if (err) { 6420 6419 rsp->hdr.Status = STATUS_INVALID_HANDLE; ··· 6570 6569 rsp->DataLength = cpu_to_le32(nbytes); 6571 6570 rsp->DataRemaining = 0; 6572 6571 rsp->Reserved2 = 0; 6573 - inc_rfc1001_len(work->response_buf, 16); 6572 + err = ksmbd_iov_pin_rsp(work, rsp, offsetof(struct smb2_write_rsp, Buffer)); 6573 + if (err) 6574 + goto out; 6574 6575 ksmbd_fd_put(work, fp); 6575 6576 return 0; 6576 6577 ··· 6619 6616 6620 6617 rsp->StructureSize = cpu_to_le16(4); 6621 6618 rsp->Reserved = 0; 6622 - inc_rfc1001_len(work->response_buf, 4); 6623 - return 0; 6619 + return ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_flush_rsp)); 6624 6620 6625 6621 out: 6626 - if (err) { 6627 - rsp->hdr.Status = STATUS_INVALID_HANDLE; 6628 - smb2_set_err_rsp(work); 6629 - } 6630 - 6622 + rsp->hdr.Status = STATUS_INVALID_HANDLE; 6623 + smb2_set_err_rsp(work); 6631 6624 return err; 6632 6625 } 6633 6626 ··· 7077 7078 goto out; 7078 7079 } 7079 7080 7080 - init_smb2_rsp_hdr(work); 7081 - smb2_set_err_rsp(work); 7082 7081 rsp->hdr.Status = 7083 7082 STATUS_RANGE_NOT_LOCKED; 7084 7083 kfree(smb_lock); ··· 7111 7114 ksmbd_debug(SMB, "successful in taking lock\n"); 7112 7115 rsp->hdr.Status = STATUS_SUCCESS; 7113 7116 rsp->Reserved = 0; 7114 - inc_rfc1001_len(work->response_buf, 4); 7117 + err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lock_rsp)); 7118 + if (err) 7119 + goto out; 7120 + 7115 7121 ksmbd_fd_put(work, fp); 7116 7122 return 0; 7117 7123 ··· 7910 7910 rsp->Reserved = cpu_to_le16(0); 7911 7911 rsp->Flags = cpu_to_le32(0); 7912 7912 rsp->Reserved2 = cpu_to_le32(0); 7913 - inc_rfc1001_len(work->response_buf, 48 + nbytes); 7914 - 7915 - return 0; 7913 + ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_ioctl_rsp) + nbytes); 7914 + if (!ret) 7915 + return ret; 7916 7916 7917 7917 out: 7918 7918 if (ret == -EACCES) ··· 8047 8047 rsp->Reserved2 = 0; 8048 8048 rsp->VolatileFid = volatile_id; 8049 8049 rsp->PersistentFid = persistent_id; 8050 - inc_rfc1001_len(work->response_buf, 24); 8051 - return; 8050 + ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break)); 8051 + if (!ret) 8052 + return; 8052 8053 8053 8054 err_out: 8054 8055 opinfo->op_state = OPLOCK_STATE_NONE; ··· 8199 8198 memcpy(rsp->LeaseKey, req->LeaseKey, 16); 8200 8199 rsp->LeaseState = lease_state; 8201 8200 rsp->LeaseDuration = 0; 8202 - inc_rfc1001_len(work->response_buf, 36); 8203 - return; 8201 + ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack)); 8202 + if (!ret) 8203 + return; 8204 8204 8205 8205 err_out: 8206 8206 opinfo->op_state = OPLOCK_STATE_NONE; ··· 8339 8337 void smb2_set_sign_rsp(struct ksmbd_work *work) 8340 8338 { 8341 8339 struct smb2_hdr *hdr; 8342 - struct smb2_hdr *req_hdr; 8343 8340 char signature[SMB2_HMACSHA256_SIZE]; 8344 - struct kvec iov[2]; 8345 - size_t len; 8341 + struct kvec *iov; 8346 8342 int n_vec = 1; 8347 8343 8348 - hdr = smb2_get_msg(work->response_buf); 8349 - if (work->next_smb2_rsp_hdr_off) 8350 - hdr = ksmbd_resp_buf_next(work); 8351 - 8352 - req_hdr = ksmbd_req_buf_next(work); 8353 - 8354 - if (!work->next_smb2_rsp_hdr_off) { 8355 - len = get_rfc1002_len(work->response_buf); 8356 - if (req_hdr->NextCommand) 8357 - len = ALIGN(len, 8); 8358 - } else { 8359 - len = get_rfc1002_len(work->response_buf) - 8360 - work->next_smb2_rsp_hdr_off; 8361 - len = ALIGN(len, 8); 8362 - } 8363 - 8364 - if (req_hdr->NextCommand) 8365 - hdr->NextCommand = cpu_to_le32(len); 8366 - 8344 + hdr = ksmbd_resp_buf_curr(work); 8367 8345 hdr->Flags |= SMB2_FLAGS_SIGNED; 8368 8346 memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE); 8369 8347 8370 - iov[0].iov_base = (char *)&hdr->ProtocolId; 8371 - iov[0].iov_len = len; 8372 - 8373 - if (work->aux_payload_sz) { 8374 - iov[0].iov_len -= work->aux_payload_sz; 8375 - 8376 - iov[1].iov_base = work->aux_payload_buf; 8377 - iov[1].iov_len = work->aux_payload_sz; 8348 + if (hdr->Command == SMB2_READ) { 8349 + iov = &work->iov[work->iov_idx - 1]; 8378 8350 n_vec++; 8351 + } else { 8352 + iov = &work->iov[work->iov_idx]; 8379 8353 } 8380 8354 8381 8355 if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec, ··· 8427 8449 void smb3_set_sign_rsp(struct ksmbd_work *work) 8428 8450 { 8429 8451 struct ksmbd_conn *conn = work->conn; 8430 - struct smb2_hdr *req_hdr, *hdr; 8452 + struct smb2_hdr *hdr; 8431 8453 struct channel *chann; 8432 8454 char signature[SMB2_CMACAES_SIZE]; 8433 - struct kvec iov[2]; 8455 + struct kvec *iov; 8434 8456 int n_vec = 1; 8435 - size_t len; 8436 8457 char *signing_key; 8437 8458 8438 - hdr = smb2_get_msg(work->response_buf); 8439 - if (work->next_smb2_rsp_hdr_off) 8440 - hdr = ksmbd_resp_buf_next(work); 8441 - 8442 - req_hdr = ksmbd_req_buf_next(work); 8443 - 8444 - if (!work->next_smb2_rsp_hdr_off) { 8445 - len = get_rfc1002_len(work->response_buf); 8446 - if (req_hdr->NextCommand) 8447 - len = ALIGN(len, 8); 8448 - } else { 8449 - len = get_rfc1002_len(work->response_buf) - 8450 - work->next_smb2_rsp_hdr_off; 8451 - len = ALIGN(len, 8); 8452 - } 8459 + hdr = ksmbd_resp_buf_curr(work); 8453 8460 8454 8461 if (conn->binding == false && 8455 8462 le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { ··· 8450 8487 if (!signing_key) 8451 8488 return; 8452 8489 8453 - if (req_hdr->NextCommand) 8454 - hdr->NextCommand = cpu_to_le32(len); 8455 - 8456 8490 hdr->Flags |= SMB2_FLAGS_SIGNED; 8457 8491 memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE); 8458 - iov[0].iov_base = (char *)&hdr->ProtocolId; 8459 - iov[0].iov_len = len; 8460 - if (work->aux_payload_sz) { 8461 - iov[0].iov_len -= work->aux_payload_sz; 8462 - iov[1].iov_base = work->aux_payload_buf; 8463 - iov[1].iov_len = work->aux_payload_sz; 8492 + 8493 + if (hdr->Command == SMB2_READ) { 8494 + iov = &work->iov[work->iov_idx - 1]; 8464 8495 n_vec++; 8496 + } else { 8497 + iov = &work->iov[work->iov_idx]; 8465 8498 } 8466 8499 8467 - if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature)) 8500 + if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, 8501 + signature)) 8468 8502 memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE); 8469 8503 } 8470 8504 ··· 8528 8568 8529 8569 int smb3_encrypt_resp(struct ksmbd_work *work) 8530 8570 { 8531 - char *buf = work->response_buf; 8532 - struct kvec iov[3]; 8571 + struct kvec *iov = work->iov; 8533 8572 int rc = -ENOMEM; 8534 - int buf_size = 0, rq_nvec = 2 + (work->aux_payload_sz ? 1 : 0); 8573 + void *tr_buf; 8535 8574 8536 - if (ARRAY_SIZE(iov) < rq_nvec) 8537 - return -ENOMEM; 8538 - 8539 - work->tr_buf = kzalloc(sizeof(struct smb2_transform_hdr) + 4, GFP_KERNEL); 8540 - if (!work->tr_buf) 8575 + tr_buf = kzalloc(sizeof(struct smb2_transform_hdr) + 4, GFP_KERNEL); 8576 + if (!tr_buf) 8541 8577 return rc; 8542 8578 8543 8579 /* fill transform header */ 8544 - fill_transform_hdr(work->tr_buf, buf, work->conn->cipher_type); 8580 + fill_transform_hdr(tr_buf, work->response_buf, work->conn->cipher_type); 8545 8581 8546 - iov[0].iov_base = work->tr_buf; 8582 + iov[0].iov_base = tr_buf; 8547 8583 iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4; 8548 - buf_size += iov[0].iov_len - 4; 8584 + work->tr_buf = tr_buf; 8549 8585 8550 - iov[1].iov_base = buf + 4; 8551 - iov[1].iov_len = get_rfc1002_len(buf); 8552 - if (work->aux_payload_sz) { 8553 - iov[1].iov_len = work->resp_hdr_sz - 4; 8554 - 8555 - iov[2].iov_base = work->aux_payload_buf; 8556 - iov[2].iov_len = work->aux_payload_sz; 8557 - buf_size += iov[2].iov_len; 8558 - } 8559 - buf_size += iov[1].iov_len; 8560 - work->resp_hdr_sz = iov[1].iov_len; 8561 - 8562 - rc = ksmbd_crypt_message(work, iov, rq_nvec, 1); 8563 - if (rc) 8564 - return rc; 8565 - 8566 - memmove(buf, iov[1].iov_base, iov[1].iov_len); 8567 - *(__be32 *)work->tr_buf = cpu_to_be32(buf_size); 8568 - 8569 - return rc; 8586 + return ksmbd_crypt_message(work, iov, work->iov_idx + 1, 1); 8570 8587 } 8571 8588 8572 8589 bool smb3_is_transform_hdr(void *buf)
+1 -1
fs/smb/server/smb2pdu.h
··· 361 361 __u8 Flags; 362 362 __u8 EaNameLength; 363 363 __le16 EaValueLength; 364 - char name[1]; 364 + char name[]; 365 365 /* optionally followed by value */ 366 366 } __packed; /* level 15 Query */ 367 367
+4 -9
fs/smb/server/smb_common.c
··· 319 319 struct smb_hdr *rsp_hdr = (struct smb_hdr *)work->response_buf; 320 320 struct smb_hdr *rcv_hdr = (struct smb_hdr *)work->request_buf; 321 321 322 - /* 323 - * Remove 4 byte direct TCP header. 324 - */ 325 - *(__be32 *)work->response_buf = 326 - cpu_to_be32(sizeof(struct smb_hdr) - 4); 327 - 328 322 rsp_hdr->Command = SMB_COM_NEGOTIATE; 329 323 *(__le32 *)rsp_hdr->Protocol = SMB1_PROTO_NUMBER; 330 324 rsp_hdr->Flags = SMBFLG_RESPONSE; ··· 554 560 555 561 ksmbd_debug(SMB, "Unsupported SMB1 protocol\n"); 556 562 557 - /* Add 2 byte bcc and 2 byte DialectIndex. */ 558 - inc_rfc1001_len(work->response_buf, 4); 559 - neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS; 563 + if (ksmbd_iov_pin_rsp(work, (void *)neg_rsp, 564 + sizeof(struct smb_negotiate_rsp) - 4)) 565 + return -ENOMEM; 560 566 567 + neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS; 561 568 neg_rsp->hdr.WordCount = 1; 562 569 neg_rsp->DialectIndex = cpu_to_le16(work->conn->dialect); 563 570 neg_rsp->ByteCount = 0;
+19 -10
fs/smb/server/transport_rdma.c
··· 1241 1241 1242 1242 //FIXME: skip RFC1002 header.. 1243 1243 buflen -= 4; 1244 - iov[0].iov_base += 4; 1245 - iov[0].iov_len -= 4; 1246 1244 1247 1245 remaining_data_length = buflen; 1248 1246 ksmbd_debug(RDMA, "Sending smb (RDMA): smb_len=%u\n", buflen); 1249 1247 1250 1248 smb_direct_send_ctx_init(st, &send_ctx, need_invalidate, remote_key); 1251 - start = i = 0; 1249 + start = i = 1; 1252 1250 buflen = 0; 1253 1251 while (true) { 1254 1252 buflen += iov[i].iov_len; ··· 1364 1366 LIST_HEAD(msg_list); 1365 1367 char *desc_buf; 1366 1368 int credits_needed; 1367 - unsigned int desc_buf_len; 1368 - size_t total_length = 0; 1369 + unsigned int desc_buf_len, desc_num = 0; 1369 1370 1370 1371 if (t->status != SMB_DIRECT_CS_CONNECTED) 1371 1372 return -ENOTCONN; 1373 + 1374 + if (buf_len > t->max_rdma_rw_size) 1375 + return -EINVAL; 1372 1376 1373 1377 /* calculate needed credits */ 1374 1378 credits_needed = 0; 1375 1379 desc_buf = buf; 1376 1380 for (i = 0; i < desc_len / sizeof(*desc); i++) { 1381 + if (!buf_len) 1382 + break; 1383 + 1377 1384 desc_buf_len = le32_to_cpu(desc[i].length); 1385 + if (!desc_buf_len) 1386 + return -EINVAL; 1387 + 1388 + if (desc_buf_len > buf_len) { 1389 + desc_buf_len = buf_len; 1390 + desc[i].length = cpu_to_le32(desc_buf_len); 1391 + buf_len = 0; 1392 + } 1378 1393 1379 1394 credits_needed += calc_rw_credits(t, desc_buf, desc_buf_len); 1380 1395 desc_buf += desc_buf_len; 1381 - total_length += desc_buf_len; 1382 - if (desc_buf_len == 0 || total_length > buf_len || 1383 - total_length > t->max_rdma_rw_size) 1384 - return -EINVAL; 1396 + buf_len -= desc_buf_len; 1397 + desc_num++; 1385 1398 } 1386 1399 1387 1400 ksmbd_debug(RDMA, "RDMA %s, len %#x, needed credits %#x\n", ··· 1404 1395 1405 1396 /* build rdma_rw_ctx for each descriptor */ 1406 1397 desc_buf = buf; 1407 - for (i = 0; i < desc_len / sizeof(*desc); i++) { 1398 + for (i = 0; i < desc_num; i++) { 1408 1399 msg = kzalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) + 1409 1400 sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL); 1410 1401 if (!msg) {
+2 -2
fs/smb/server/vfs.c
··· 367 367 * @fid: file id of open file 368 368 * @count: read byte count 369 369 * @pos: file pos 370 + * @rbuf: read data buffer 370 371 * 371 372 * Return: number of read bytes on success, otherwise error 372 373 */ 373 374 int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, 374 - loff_t *pos) 375 + loff_t *pos, char *rbuf) 375 376 { 376 377 struct file *filp = fp->filp; 377 378 ssize_t nbytes = 0; 378 - char *rbuf = work->aux_payload_buf; 379 379 struct inode *inode = file_inode(filp); 380 380 381 381 if (S_ISDIR(inode->i_mode))
+2 -2
fs/smb/server/vfs.h
··· 76 76 struct dentry *dentry, __le32 *daccess); 77 77 int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode); 78 78 int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode); 79 - int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, 80 - size_t count, loff_t *pos); 79 + int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, 80 + loff_t *pos, char *rbuf); 81 81 int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, 82 82 char *buf, size_t count, loff_t *pos, bool sync, 83 83 ssize_t *written);