Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
0004  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
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      * Make sure that this really is an SMB, that it is a response.
0018      */
0019     if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
0020         return 1;
0021     return 0;
0022 }
0023 
0024 /*
0025  *  The following table defines the expected "StructureSize" of SMB2 requests
0026  *  in order by SMB2 command.  This is similar to "wct" in SMB/CIFS requests.
0027  *
0028  *  Note that commands are defined in smb2pdu.h in le16 but the array below is
0029  *  indexed by command in host byte order
0030  */
0031 static const __le16 smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
0032     /* SMB2_NEGOTIATE */ cpu_to_le16(36),
0033     /* SMB2_SESSION_SETUP */ cpu_to_le16(25),
0034     /* SMB2_LOGOFF */ cpu_to_le16(4),
0035     /* SMB2_TREE_CONNECT */ cpu_to_le16(9),
0036     /* SMB2_TREE_DISCONNECT */ cpu_to_le16(4),
0037     /* SMB2_CREATE */ cpu_to_le16(57),
0038     /* SMB2_CLOSE */ cpu_to_le16(24),
0039     /* SMB2_FLUSH */ cpu_to_le16(24),
0040     /* SMB2_READ */ cpu_to_le16(49),
0041     /* SMB2_WRITE */ cpu_to_le16(49),
0042     /* SMB2_LOCK */ cpu_to_le16(48),
0043     /* SMB2_IOCTL */ cpu_to_le16(57),
0044     /* SMB2_CANCEL */ cpu_to_le16(4),
0045     /* SMB2_ECHO */ cpu_to_le16(4),
0046     /* SMB2_QUERY_DIRECTORY */ cpu_to_le16(33),
0047     /* SMB2_CHANGE_NOTIFY */ cpu_to_le16(32),
0048     /* SMB2_QUERY_INFO */ cpu_to_le16(41),
0049     /* SMB2_SET_INFO */ cpu_to_le16(33),
0050     /* use 44 for lease break */
0051     /* SMB2_OPLOCK_BREAK */ cpu_to_le16(36)
0052 };
0053 
0054 /*
0055  * The size of the variable area depends on the offset and length fields
0056  * located in different fields for various SMB2 requests. SMB2 requests
0057  * with no variable length info, show an offset of zero for the offset field.
0058  */
0059 static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
0060     /* SMB2_NEGOTIATE */ true,
0061     /* SMB2_SESSION_SETUP */ true,
0062     /* SMB2_LOGOFF */ false,
0063     /* SMB2_TREE_CONNECT */ true,
0064     /* SMB2_TREE_DISCONNECT */ false,
0065     /* SMB2_CREATE */ true,
0066     /* SMB2_CLOSE */ false,
0067     /* SMB2_FLUSH */ false,
0068     /* SMB2_READ */ true,
0069     /* SMB2_WRITE */ true,
0070     /* SMB2_LOCK */ true,
0071     /* SMB2_IOCTL */ true,
0072     /* SMB2_CANCEL */ false, /* BB CHECK this not listed in documentation */
0073     /* SMB2_ECHO */ false,
0074     /* SMB2_QUERY_DIRECTORY */ true,
0075     /* SMB2_CHANGE_NOTIFY */ false,
0076     /* SMB2_QUERY_INFO */ true,
0077     /* SMB2_SET_INFO */ true,
0078     /* SMB2_OPLOCK_BREAK */ false
0079 };
0080 
0081 /*
0082  * Set length of the data area and the offset to arguments.
0083  * if they are invalid, return error.
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      * Following commands have data areas so we have to get the location
0095      * of the data buffer offset and data buffer length for the particular
0096      * command.
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          * smb2_lock request size is 48 included single
0156          * smb2_lock_element structure size.
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  * Calculate the size of the SMB message based on the fixed header
0188  * portion, the number of word parameters and the data portion of the message.
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; /* the offset from the beginning of SMB to data area */
0195     unsigned int data_length; /* the length of the variable length data area */
0196     int ret;
0197 
0198     /* Structure Size has already been checked to make sure it is 64 */
0199     *len = le16_to_cpu(hdr->StructureSize);
0200 
0201     /*
0202      * StructureSize2, ie length of fixed parameter area has already
0203      * been checked to make sure it is the correct length.
0204      */
0205     *len += le16_to_cpu(pdu->StructureSize2);
0206     /*
0207      * StructureSize2 of smb2_lock pdu is set to 48, indicating
0208      * the size of smb2 lock request with single smb2_lock_element
0209      * regardless of number of locks. Subtract single
0210      * smb2_lock_element for correct buffer size check.
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          * Check to make sure that data area begins after fixed area,
0227          * Note that last byte of the fixed area is part of data area
0228          * for some commands, typically those with odd StructureSize,
0229          * so we must add one to the calculation.
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;  /* calculated length */
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             /* error packets have 9 byte structure size */
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             /* special case for SMB2.1 lease break message */
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         /* client can return one byte more due to implied bcc[0] */
0404         if (clc_len == len + 1)
0405             goto validate_credit;
0406 
0407         /*
0408          * Some windows servers (win2016) will pad also the final
0409          * PDU in a compound to 8 bytes.
0410          */
0411         if (ALIGN(clc_len, 8) == len)
0412             goto validate_credit;
0413 
0414         /*
0415          * windows client also pad up to 8 bytes when compounding.
0416          * If pad is longer than eight bytes, log the server behavior
0417          * (once), since may indicate a problem but allow it and
0418          * continue since the frame is parseable.
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 }