0001
0002
0003
0004
0005
0006
0007 #include "glob.h"
0008 #include "nterr.h"
0009 #include "smb_common.h"
0010 #include "smbstatus.h"
0011 #include "mgmt/user_session.h"
0012 #include "connection.h"
0013
0014 static int check_smb2_hdr(struct smb2_hdr *hdr)
0015 {
0016
0017
0018
0019 if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
0020 return 1;
0021 return 0;
0022 }
0023
0024
0025
0026
0027
0028
0029
0030
0031 static const __le16 smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
0032 cpu_to_le16(36),
0033 cpu_to_le16(25),
0034 cpu_to_le16(4),
0035 cpu_to_le16(9),
0036 cpu_to_le16(4),
0037 cpu_to_le16(57),
0038 cpu_to_le16(24),
0039 cpu_to_le16(24),
0040 cpu_to_le16(49),
0041 cpu_to_le16(49),
0042 cpu_to_le16(48),
0043 cpu_to_le16(57),
0044 cpu_to_le16(4),
0045 cpu_to_le16(4),
0046 cpu_to_le16(33),
0047 cpu_to_le16(32),
0048 cpu_to_le16(41),
0049 cpu_to_le16(33),
0050
0051 cpu_to_le16(36)
0052 };
0053
0054
0055
0056
0057
0058
0059 static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
0060 true,
0061 true,
0062 false,
0063 true,
0064 false,
0065 true,
0066 false,
0067 false,
0068 true,
0069 true,
0070 true,
0071 true,
0072 false,
0073 false,
0074 true,
0075 false,
0076 true,
0077 true,
0078 false
0079 };
0080
0081
0082
0083
0084
0085 static int smb2_get_data_area_len(unsigned int *off, unsigned int *len,
0086 struct smb2_hdr *hdr)
0087 {
0088 int ret = 0;
0089
0090 *off = 0;
0091 *len = 0;
0092
0093
0094
0095
0096
0097
0098 switch (hdr->Command) {
0099 case SMB2_SESSION_SETUP:
0100 *off = le16_to_cpu(((struct smb2_sess_setup_req *)hdr)->SecurityBufferOffset);
0101 *len = le16_to_cpu(((struct smb2_sess_setup_req *)hdr)->SecurityBufferLength);
0102 break;
0103 case SMB2_TREE_CONNECT:
0104 *off = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathOffset);
0105 *len = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathLength);
0106 break;
0107 case SMB2_CREATE:
0108 {
0109 if (((struct smb2_create_req *)hdr)->CreateContextsLength) {
0110 *off = le32_to_cpu(((struct smb2_create_req *)
0111 hdr)->CreateContextsOffset);
0112 *len = le32_to_cpu(((struct smb2_create_req *)
0113 hdr)->CreateContextsLength);
0114 break;
0115 }
0116
0117 *off = le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset);
0118 *len = le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength);
0119 break;
0120 }
0121 case SMB2_QUERY_INFO:
0122 *off = le16_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferOffset);
0123 *len = le32_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferLength);
0124 break;
0125 case SMB2_SET_INFO:
0126 *off = le16_to_cpu(((struct smb2_set_info_req *)hdr)->BufferOffset);
0127 *len = le32_to_cpu(((struct smb2_set_info_req *)hdr)->BufferLength);
0128 break;
0129 case SMB2_READ:
0130 *off = le16_to_cpu(((struct smb2_read_req *)hdr)->ReadChannelInfoOffset);
0131 *len = le16_to_cpu(((struct smb2_read_req *)hdr)->ReadChannelInfoLength);
0132 break;
0133 case SMB2_WRITE:
0134 if (((struct smb2_write_req *)hdr)->DataOffset ||
0135 ((struct smb2_write_req *)hdr)->Length) {
0136 *off = max_t(unsigned int,
0137 le16_to_cpu(((struct smb2_write_req *)hdr)->DataOffset),
0138 offsetof(struct smb2_write_req, Buffer));
0139 *len = le32_to_cpu(((struct smb2_write_req *)hdr)->Length);
0140 break;
0141 }
0142
0143 *off = le16_to_cpu(((struct smb2_write_req *)hdr)->WriteChannelInfoOffset);
0144 *len = le16_to_cpu(((struct smb2_write_req *)hdr)->WriteChannelInfoLength);
0145 break;
0146 case SMB2_QUERY_DIRECTORY:
0147 *off = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameOffset);
0148 *len = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameLength);
0149 break;
0150 case SMB2_LOCK:
0151 {
0152 int lock_count;
0153
0154
0155
0156
0157
0158 lock_count = le16_to_cpu(((struct smb2_lock_req *)hdr)->LockCount) - 1;
0159 if (lock_count > 0) {
0160 *off = __SMB2_HEADER_STRUCTURE_SIZE + 48;
0161 *len = sizeof(struct smb2_lock_element) * lock_count;
0162 }
0163 break;
0164 }
0165 case SMB2_IOCTL:
0166 *off = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputOffset);
0167 *len = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputCount);
0168 break;
0169 default:
0170 ksmbd_debug(SMB, "no length check for command\n");
0171 break;
0172 }
0173
0174 if (*off > 4096) {
0175 ksmbd_debug(SMB, "offset %d too large\n", *off);
0176 ret = -EINVAL;
0177 } else if ((u64)*off + *len > MAX_STREAM_PROT_LEN) {
0178 ksmbd_debug(SMB, "Request is larger than maximum stream protocol length(%u): %llu\n",
0179 MAX_STREAM_PROT_LEN, (u64)*off + *len);
0180 ret = -EINVAL;
0181 }
0182
0183 return ret;
0184 }
0185
0186
0187
0188
0189
0190 static int smb2_calc_size(void *buf, unsigned int *len)
0191 {
0192 struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
0193 struct smb2_hdr *hdr = &pdu->hdr;
0194 unsigned int offset;
0195 unsigned int data_length;
0196 int ret;
0197
0198
0199 *len = le16_to_cpu(hdr->StructureSize);
0200
0201
0202
0203
0204
0205 *len += le16_to_cpu(pdu->StructureSize2);
0206
0207
0208
0209
0210
0211
0212 if (hdr->Command == SMB2_LOCK)
0213 *len -= sizeof(struct smb2_lock_element);
0214
0215 if (has_smb2_data_area[le16_to_cpu(hdr->Command)] == false)
0216 goto calc_size_exit;
0217
0218 ret = smb2_get_data_area_len(&offset, &data_length, hdr);
0219 if (ret)
0220 return ret;
0221 ksmbd_debug(SMB, "SMB2 data length %u offset %u\n", data_length,
0222 offset);
0223
0224 if (data_length > 0) {
0225
0226
0227
0228
0229
0230
0231 if (offset + 1 < *len) {
0232 ksmbd_debug(SMB,
0233 "data area offset %d overlaps SMB2 header %u\n",
0234 offset + 1, *len);
0235 return -EINVAL;
0236 }
0237
0238 *len = offset + data_length;
0239 }
0240
0241 calc_size_exit:
0242 ksmbd_debug(SMB, "SMB2 len %u\n", *len);
0243 return 0;
0244 }
0245
0246 static inline int smb2_query_info_req_len(struct smb2_query_info_req *h)
0247 {
0248 return le32_to_cpu(h->InputBufferLength) +
0249 le32_to_cpu(h->OutputBufferLength);
0250 }
0251
0252 static inline int smb2_set_info_req_len(struct smb2_set_info_req *h)
0253 {
0254 return le32_to_cpu(h->BufferLength);
0255 }
0256
0257 static inline int smb2_read_req_len(struct smb2_read_req *h)
0258 {
0259 return le32_to_cpu(h->Length);
0260 }
0261
0262 static inline int smb2_write_req_len(struct smb2_write_req *h)
0263 {
0264 return le32_to_cpu(h->Length);
0265 }
0266
0267 static inline int smb2_query_dir_req_len(struct smb2_query_directory_req *h)
0268 {
0269 return le32_to_cpu(h->OutputBufferLength);
0270 }
0271
0272 static inline int smb2_ioctl_req_len(struct smb2_ioctl_req *h)
0273 {
0274 return le32_to_cpu(h->InputCount) +
0275 le32_to_cpu(h->OutputCount);
0276 }
0277
0278 static inline int smb2_ioctl_resp_len(struct smb2_ioctl_req *h)
0279 {
0280 return le32_to_cpu(h->MaxInputResponse) +
0281 le32_to_cpu(h->MaxOutputResponse);
0282 }
0283
0284 static int smb2_validate_credit_charge(struct ksmbd_conn *conn,
0285 struct smb2_hdr *hdr)
0286 {
0287 unsigned int req_len = 0, expect_resp_len = 0, calc_credit_num, max_len;
0288 unsigned short credit_charge = le16_to_cpu(hdr->CreditCharge);
0289 void *__hdr = hdr;
0290 int ret = 0;
0291
0292 switch (hdr->Command) {
0293 case SMB2_QUERY_INFO:
0294 req_len = smb2_query_info_req_len(__hdr);
0295 break;
0296 case SMB2_SET_INFO:
0297 req_len = smb2_set_info_req_len(__hdr);
0298 break;
0299 case SMB2_READ:
0300 req_len = smb2_read_req_len(__hdr);
0301 break;
0302 case SMB2_WRITE:
0303 req_len = smb2_write_req_len(__hdr);
0304 break;
0305 case SMB2_QUERY_DIRECTORY:
0306 req_len = smb2_query_dir_req_len(__hdr);
0307 break;
0308 case SMB2_IOCTL:
0309 req_len = smb2_ioctl_req_len(__hdr);
0310 expect_resp_len = smb2_ioctl_resp_len(__hdr);
0311 break;
0312 case SMB2_CANCEL:
0313 return 0;
0314 default:
0315 req_len = 1;
0316 break;
0317 }
0318
0319 credit_charge = max_t(unsigned short, credit_charge, 1);
0320 max_len = max_t(unsigned int, req_len, expect_resp_len);
0321 calc_credit_num = DIV_ROUND_UP(max_len, SMB2_MAX_BUFFER_SIZE);
0322
0323 if (credit_charge < calc_credit_num) {
0324 ksmbd_debug(SMB, "Insufficient credit charge, given: %d, needed: %d\n",
0325 credit_charge, calc_credit_num);
0326 return 1;
0327 } else if (credit_charge > conn->vals->max_credits) {
0328 ksmbd_debug(SMB, "Too large credit charge: %d\n", credit_charge);
0329 return 1;
0330 }
0331
0332 spin_lock(&conn->credits_lock);
0333 if (credit_charge > conn->total_credits) {
0334 ksmbd_debug(SMB, "Insufficient credits granted, given: %u, granted: %u\n",
0335 credit_charge, conn->total_credits);
0336 ret = 1;
0337 }
0338
0339 if ((u64)conn->outstanding_credits + credit_charge > conn->total_credits) {
0340 ksmbd_debug(SMB, "Limits exceeding the maximum allowable outstanding requests, given : %u, pending : %u\n",
0341 credit_charge, conn->outstanding_credits);
0342 ret = 1;
0343 } else
0344 conn->outstanding_credits += credit_charge;
0345
0346 spin_unlock(&conn->credits_lock);
0347
0348 return ret;
0349 }
0350
0351 int ksmbd_smb2_check_message(struct ksmbd_work *work)
0352 {
0353 struct smb2_pdu *pdu = ksmbd_req_buf_next(work);
0354 struct smb2_hdr *hdr = &pdu->hdr;
0355 int command;
0356 __u32 clc_len;
0357 __u32 len = get_rfc1002_len(work->request_buf);
0358
0359 if (le32_to_cpu(hdr->NextCommand) > 0)
0360 len = le32_to_cpu(hdr->NextCommand);
0361 else if (work->next_smb2_rcv_hdr_off)
0362 len -= work->next_smb2_rcv_hdr_off;
0363
0364 if (check_smb2_hdr(hdr))
0365 return 1;
0366
0367 if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
0368 ksmbd_debug(SMB, "Illegal structure size %u\n",
0369 le16_to_cpu(hdr->StructureSize));
0370 return 1;
0371 }
0372
0373 command = le16_to_cpu(hdr->Command);
0374 if (command >= NUMBER_OF_SMB2_COMMANDS) {
0375 ksmbd_debug(SMB, "Illegal SMB2 command %d\n", command);
0376 return 1;
0377 }
0378
0379 if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
0380 if (command != SMB2_OPLOCK_BREAK_HE &&
0381 (hdr->Status == 0 || pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) {
0382
0383 ksmbd_debug(SMB,
0384 "Illegal request size %u for command %d\n",
0385 le16_to_cpu(pdu->StructureSize2), command);
0386 return 1;
0387 } else if (command == SMB2_OPLOCK_BREAK_HE &&
0388 hdr->Status == 0 &&
0389 le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 &&
0390 le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) {
0391
0392 ksmbd_debug(SMB,
0393 "Illegal request size %d for oplock break\n",
0394 le16_to_cpu(pdu->StructureSize2));
0395 return 1;
0396 }
0397 }
0398
0399 if (smb2_calc_size(hdr, &clc_len))
0400 return 1;
0401
0402 if (len != clc_len) {
0403
0404 if (clc_len == len + 1)
0405 goto validate_credit;
0406
0407
0408
0409
0410
0411 if (ALIGN(clc_len, 8) == len)
0412 goto validate_credit;
0413
0414
0415
0416
0417
0418
0419
0420 if (clc_len < len) {
0421 ksmbd_debug(SMB,
0422 "cli req padded more than expected. Length %d not %d for cmd:%d mid:%llu\n",
0423 len, clc_len, command,
0424 le64_to_cpu(hdr->MessageId));
0425 goto validate_credit;
0426 }
0427
0428 ksmbd_debug(SMB,
0429 "cli req too short, len %d not %d. cmd:%d mid:%llu\n",
0430 len, clc_len, command,
0431 le64_to_cpu(hdr->MessageId));
0432
0433 return 1;
0434 }
0435
0436 validate_credit:
0437 if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) &&
0438 smb2_validate_credit_charge(work->conn, hdr)) {
0439 work->conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
0440 return 1;
0441 }
0442
0443 return 0;
0444 }
0445
0446 int smb2_negotiate_request(struct ksmbd_work *work)
0447 {
0448 return ksmbd_smb_negotiate_common(work, SMB2_NEGOTIATE_HE);
0449 }