cifs: add server->vals->header_preamble_size
This variable is set to 4 for all protocol versions and replaces the hardcoded constant 4 throughought the code. This will later be updated to reflect whether a response packet has a 4 byte length preamble or not once we start removing this field from the SMB2+ dialects. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
This commit is contained in:
parent
21a4e14aae
commit
93012bf984
@ -468,6 +468,7 @@ struct smb_version_values {
|
|||||||
__u32 exclusive_lock_type;
|
__u32 exclusive_lock_type;
|
||||||
__u32 shared_lock_type;
|
__u32 shared_lock_type;
|
||||||
__u32 unlock_lock_type;
|
__u32 unlock_lock_type;
|
||||||
|
size_t header_preamble_size;
|
||||||
size_t header_size;
|
size_t header_size;
|
||||||
size_t max_header_size;
|
size_t max_header_size;
|
||||||
size_t read_rsp_size;
|
size_t read_rsp_size;
|
||||||
|
@ -1454,7 +1454,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
unsigned int data_offset, data_len;
|
unsigned int data_offset, data_len;
|
||||||
struct cifs_readdata *rdata = mid->callback_data;
|
struct cifs_readdata *rdata = mid->callback_data;
|
||||||
char *buf = server->smallbuf;
|
char *buf = server->smallbuf;
|
||||||
unsigned int buflen = get_rfc1002_length(buf) + 4;
|
unsigned int buflen = get_rfc1002_length(buf) +
|
||||||
|
server->vals->header_preamble_size;
|
||||||
bool use_rdma_mr = false;
|
bool use_rdma_mr = false;
|
||||||
|
|
||||||
cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
|
cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
|
||||||
@ -1504,7 +1505,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
return cifs_readv_discard(server, mid);
|
return cifs_readv_discard(server, mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
data_offset = server->ops->read_data_offset(buf) + 4;
|
data_offset = server->ops->read_data_offset(buf) +
|
||||||
|
server->vals->header_preamble_size;
|
||||||
if (data_offset < server->total_read) {
|
if (data_offset < server->total_read) {
|
||||||
/*
|
/*
|
||||||
* win2k8 sometimes sends an offset of 0 when the read
|
* win2k8 sometimes sends an offset of 0 when the read
|
||||||
|
@ -775,7 +775,8 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
unsigned int pdu_length = get_rfc1002_length(buf);
|
unsigned int pdu_length = get_rfc1002_length(buf);
|
||||||
|
|
||||||
/* make sure this will fit in a large buffer */
|
/* make sure this will fit in a large buffer */
|
||||||
if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - 4) {
|
if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) -
|
||||||
|
server->vals->header_preamble_size) {
|
||||||
cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length);
|
cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length);
|
||||||
cifs_reconnect(server);
|
cifs_reconnect(server);
|
||||||
wake_up(&server->response_q);
|
wake_up(&server->response_q);
|
||||||
@ -791,7 +792,9 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
|
|
||||||
/* now read the rest */
|
/* now read the rest */
|
||||||
length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
|
length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
|
||||||
pdu_length - HEADER_SIZE(server) + 1 + 4);
|
pdu_length - HEADER_SIZE(server) + 1
|
||||||
|
+ server->vals->header_preamble_size);
|
||||||
|
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
return length;
|
return length;
|
||||||
server->total_read += length;
|
server->total_read += length;
|
||||||
@ -884,7 +887,8 @@ cifs_demultiplex_thread(void *p)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* make sure we have enough to get to the MID */
|
/* make sure we have enough to get to the MID */
|
||||||
if (pdu_length < HEADER_SIZE(server) - 1 - 4) {
|
if (pdu_length < HEADER_SIZE(server) - 1 -
|
||||||
|
server->vals->header_preamble_size) {
|
||||||
cifs_dbg(VFS, "SMB response too short (%u bytes)\n",
|
cifs_dbg(VFS, "SMB response too short (%u bytes)\n",
|
||||||
pdu_length);
|
pdu_length);
|
||||||
cifs_reconnect(server);
|
cifs_reconnect(server);
|
||||||
@ -893,8 +897,10 @@ cifs_demultiplex_thread(void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read down to the MID */
|
/* read down to the MID */
|
||||||
length = cifs_read_from_socket(server, buf + 4,
|
length = cifs_read_from_socket(server,
|
||||||
HEADER_SIZE(server) - 1 - 4);
|
buf + server->vals->header_preamble_size,
|
||||||
|
HEADER_SIZE(server) - 1
|
||||||
|
- server->vals->header_preamble_size);
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
continue;
|
continue;
|
||||||
server->total_read += length;
|
server->total_read += length;
|
||||||
|
@ -1122,6 +1122,7 @@ struct smb_version_values smb1_values = {
|
|||||||
.exclusive_lock_type = 0,
|
.exclusive_lock_type = 0,
|
||||||
.shared_lock_type = LOCKING_ANDX_SHARED_LOCK,
|
.shared_lock_type = LOCKING_ANDX_SHARED_LOCK,
|
||||||
.unlock_lock_type = 0,
|
.unlock_lock_type = 0,
|
||||||
|
.header_preamble_size = 4,
|
||||||
.header_size = sizeof(struct smb_hdr),
|
.header_size = sizeof(struct smb_hdr),
|
||||||
.max_header_size = MAX_CIFS_HDR_SIZE,
|
.max_header_size = MAX_CIFS_HDR_SIZE,
|
||||||
.read_rsp_size = sizeof(READ_RSP),
|
.read_rsp_size = sizeof(READ_RSP),
|
||||||
|
@ -150,7 +150,8 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) {
|
if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE -
|
||||||
|
srvr->vals->header_preamble_size) {
|
||||||
cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
|
cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
|
||||||
mid);
|
mid);
|
||||||
return 1;
|
return 1;
|
||||||
@ -189,26 +190,26 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (4 + len != length) {
|
if (srvr->vals->header_preamble_size + len != length) {
|
||||||
cifs_dbg(VFS, "Total length %u RFC1002 length %u mismatch mid %llu\n",
|
cifs_dbg(VFS, "Total length %u RFC1002 length %u mismatch mid %llu\n",
|
||||||
length, 4 + len, mid);
|
length, srvr->vals->header_preamble_size + len, mid);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
clc_len = smb2_calc_size(hdr);
|
clc_len = smb2_calc_size(hdr);
|
||||||
|
|
||||||
if (4 + len != clc_len) {
|
if (srvr->vals->header_preamble_size + len != clc_len) {
|
||||||
cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
|
cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
|
||||||
clc_len, 4 + len, mid);
|
clc_len, srvr->vals->header_preamble_size + len, mid);
|
||||||
/* create failed on symlink */
|
/* create failed on symlink */
|
||||||
if (command == SMB2_CREATE_HE &&
|
if (command == SMB2_CREATE_HE &&
|
||||||
shdr->Status == STATUS_STOPPED_ON_SYMLINK)
|
shdr->Status == STATUS_STOPPED_ON_SYMLINK)
|
||||||
return 0;
|
return 0;
|
||||||
/* Windows 7 server returns 24 bytes more */
|
/* Windows 7 server returns 24 bytes more */
|
||||||
if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE)
|
if (clc_len + 24 - srvr->vals->header_preamble_size == len && command == SMB2_OPLOCK_BREAK_HE)
|
||||||
return 0;
|
return 0;
|
||||||
/* server can return one byte more due to implied bcc[0] */
|
/* server can return one byte more due to implied bcc[0] */
|
||||||
if (clc_len == 4 + len + 1)
|
if (clc_len == srvr->vals->header_preamble_size + len + 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -218,10 +219,10 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
|
|||||||
* Log the server error (once), but allow it and continue
|
* Log the server error (once), but allow it and continue
|
||||||
* since the frame is parseable.
|
* since the frame is parseable.
|
||||||
*/
|
*/
|
||||||
if (clc_len < 4 /* RFC1001 header size */ + len) {
|
if (clc_len < srvr->vals->header_preamble_size /* RFC1001 header size */ + len) {
|
||||||
printk_once(KERN_WARNING
|
printk_once(KERN_WARNING
|
||||||
"SMB2 server sent bad RFC1001 len %d not %d\n",
|
"SMB2 server sent bad RFC1001 len %d not %d\n",
|
||||||
len, clc_len - 4);
|
len, clc_len - srvr->vals->header_preamble_size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1457,6 +1457,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
unsigned int sub_offset;
|
unsigned int sub_offset;
|
||||||
unsigned int print_len;
|
unsigned int print_len;
|
||||||
unsigned int print_offset;
|
unsigned int print_offset;
|
||||||
|
struct cifs_ses *ses = tcon->ses;
|
||||||
|
struct TCP_Server_Info *server = ses->server;
|
||||||
|
|
||||||
cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
|
cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
|
||||||
|
|
||||||
@ -1479,7 +1481,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
|
if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
|
||||||
get_rfc1002_length(err_buf) + 4 < SMB2_SYMLINK_STRUCT_SIZE) {
|
get_rfc1002_length(err_buf) + server->vals->header_preamble_size < SMB2_SYMLINK_STRUCT_SIZE) {
|
||||||
kfree(utf16_path);
|
kfree(utf16_path);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -1492,13 +1494,13 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
print_len = le16_to_cpu(symlink->PrintNameLength);
|
print_len = le16_to_cpu(symlink->PrintNameLength);
|
||||||
print_offset = le16_to_cpu(symlink->PrintNameOffset);
|
print_offset = le16_to_cpu(symlink->PrintNameOffset);
|
||||||
|
|
||||||
if (get_rfc1002_length(err_buf) + 4 <
|
if (get_rfc1002_length(err_buf) + server->vals->header_preamble_size <
|
||||||
SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
|
SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
|
||||||
kfree(utf16_path);
|
kfree(utf16_path);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_rfc1002_length(err_buf) + 4 <
|
if (get_rfc1002_length(err_buf) + server->vals->header_preamble_size <
|
||||||
SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
|
SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
|
||||||
kfree(utf16_path);
|
kfree(utf16_path);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
@ -2050,7 +2052,8 @@ smb2_dir_needs_close(struct cifsFileInfo *cfile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, struct smb_rqst *old_rq)
|
fill_transform_hdr(struct TCP_Server_Info *server,
|
||||||
|
struct smb2_transform_hdr *tr_hdr, struct smb_rqst *old_rq)
|
||||||
{
|
{
|
||||||
struct smb2_sync_hdr *shdr =
|
struct smb2_sync_hdr *shdr =
|
||||||
(struct smb2_sync_hdr *)old_rq->rq_iov[1].iov_base;
|
(struct smb2_sync_hdr *)old_rq->rq_iov[1].iov_base;
|
||||||
@ -2062,7 +2065,7 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, struct smb_rqst *old_rq)
|
|||||||
tr_hdr->Flags = cpu_to_le16(0x01);
|
tr_hdr->Flags = cpu_to_le16(0x01);
|
||||||
get_random_bytes(&tr_hdr->Nonce, SMB3_AES128CMM_NONCE);
|
get_random_bytes(&tr_hdr->Nonce, SMB3_AES128CMM_NONCE);
|
||||||
memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
|
memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
|
||||||
inc_rfc1001_len(tr_hdr, sizeof(struct smb2_transform_hdr) - 4);
|
inc_rfc1001_len(tr_hdr, sizeof(struct smb2_transform_hdr) - server->vals->header_preamble_size);
|
||||||
inc_rfc1001_len(tr_hdr, orig_len);
|
inc_rfc1001_len(tr_hdr, orig_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2134,7 +2137,7 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
|
|||||||
{
|
{
|
||||||
struct smb2_transform_hdr *tr_hdr =
|
struct smb2_transform_hdr *tr_hdr =
|
||||||
(struct smb2_transform_hdr *)rqst->rq_iov[0].iov_base;
|
(struct smb2_transform_hdr *)rqst->rq_iov[0].iov_base;
|
||||||
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
|
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20 - server->vals->header_preamble_size;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
u8 sign[SMB2_SIGNATURE_SIZE] = {};
|
u8 sign[SMB2_SIGNATURE_SIZE] = {};
|
||||||
@ -2262,7 +2265,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq,
|
|||||||
goto err_free_iov;
|
goto err_free_iov;
|
||||||
|
|
||||||
/* fill the 1st iov with a transform header */
|
/* fill the 1st iov with a transform header */
|
||||||
fill_transform_hdr(tr_hdr, old_rq);
|
fill_transform_hdr(server, tr_hdr, old_rq);
|
||||||
new_rq->rq_iov[0].iov_base = tr_hdr;
|
new_rq->rq_iov[0].iov_base = tr_hdr;
|
||||||
new_rq->rq_iov[0].iov_len = sizeof(struct smb2_transform_hdr);
|
new_rq->rq_iov[0].iov_len = sizeof(struct smb2_transform_hdr);
|
||||||
|
|
||||||
@ -2344,10 +2347,10 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
memmove(buf + 4, iov[1].iov_base, buf_data_size);
|
memmove(buf + server->vals->header_preamble_size, iov[1].iov_base, buf_data_size);
|
||||||
hdr = (struct smb2_hdr *)buf;
|
hdr = (struct smb2_hdr *)buf;
|
||||||
hdr->smb2_buf_length = cpu_to_be32(buf_data_size + page_data_size);
|
hdr->smb2_buf_length = cpu_to_be32(buf_data_size + page_data_size);
|
||||||
server->total_read = buf_data_size + page_data_size + 4;
|
server->total_read = buf_data_size + page_data_size + server->vals->header_preamble_size;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -2451,7 +2454,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_offset = server->ops->read_data_offset(buf) + 4;
|
data_offset = server->ops->read_data_offset(buf) + server->vals->header_preamble_size;
|
||||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||||
use_rdma_mr = rdata->mr;
|
use_rdma_mr = rdata->mr;
|
||||||
#endif
|
#endif
|
||||||
@ -2547,11 +2550,12 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid)
|
|||||||
unsigned int npages;
|
unsigned int npages;
|
||||||
struct page **pages;
|
struct page **pages;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
unsigned int buflen = get_rfc1002_length(buf) + 4;
|
unsigned int buflen = get_rfc1002_length(buf) + server->vals->header_preamble_size;
|
||||||
int rc;
|
int rc;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
len = min_t(unsigned int, buflen, server->vals->read_rsp_size - 4 +
|
len = min_t(unsigned int, buflen, server->vals->read_rsp_size -
|
||||||
|
server->vals->header_preamble_size +
|
||||||
sizeof(struct smb2_transform_hdr)) - HEADER_SIZE(server) + 1;
|
sizeof(struct smb2_transform_hdr)) - HEADER_SIZE(server) + 1;
|
||||||
|
|
||||||
rc = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, len);
|
rc = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, len);
|
||||||
@ -2559,7 +2563,8 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid)
|
|||||||
return rc;
|
return rc;
|
||||||
server->total_read += rc;
|
server->total_read += rc;
|
||||||
|
|
||||||
len = le32_to_cpu(tr_hdr->OriginalMessageSize) + 4 -
|
len = le32_to_cpu(tr_hdr->OriginalMessageSize) +
|
||||||
|
server->vals->header_preamble_size -
|
||||||
server->vals->read_rsp_size;
|
server->vals->read_rsp_size;
|
||||||
npages = DIV_ROUND_UP(len, PAGE_SIZE);
|
npages = DIV_ROUND_UP(len, PAGE_SIZE);
|
||||||
|
|
||||||
@ -2586,7 +2591,8 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
|
|
||||||
rc = decrypt_raw_data(server, buf, server->vals->read_rsp_size - 4,
|
rc = decrypt_raw_data(server, buf, server->vals->read_rsp_size -
|
||||||
|
server->vals->header_preamble_size,
|
||||||
pages, npages, len);
|
pages, npages, len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
@ -2623,7 +2629,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
|
|||||||
struct mid_q_entry *mid_entry;
|
struct mid_q_entry *mid_entry;
|
||||||
|
|
||||||
/* switch to large buffer if too big for a small one */
|
/* switch to large buffer if too big for a small one */
|
||||||
if (pdu_length + 4 > MAX_CIFS_SMALL_BUFFER_SIZE) {
|
if (pdu_length + server->vals->header_preamble_size > MAX_CIFS_SMALL_BUFFER_SIZE) {
|
||||||
server->large_buf = true;
|
server->large_buf = true;
|
||||||
memcpy(server->bigbuf, buf, server->total_read);
|
memcpy(server->bigbuf, buf, server->total_read);
|
||||||
buf = server->bigbuf;
|
buf = server->bigbuf;
|
||||||
@ -2631,12 +2637,13 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
|
|||||||
|
|
||||||
/* now read the rest */
|
/* now read the rest */
|
||||||
length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
|
length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
|
||||||
pdu_length - HEADER_SIZE(server) + 1 + 4);
|
pdu_length - HEADER_SIZE(server) + 1 +
|
||||||
|
server->vals->header_preamble_size);
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
return length;
|
return length;
|
||||||
server->total_read += length;
|
server->total_read += length;
|
||||||
|
|
||||||
buf_size = pdu_length + 4 - sizeof(struct smb2_transform_hdr);
|
buf_size = pdu_length + server->vals->header_preamble_size - sizeof(struct smb2_transform_hdr);
|
||||||
length = decrypt_raw_data(server, buf, buf_size, NULL, 0, 0);
|
length = decrypt_raw_data(server, buf, buf_size, NULL, 0, 0);
|
||||||
if (length)
|
if (length)
|
||||||
return length;
|
return length;
|
||||||
@ -2665,7 +2672,7 @@ smb3_receive_transform(struct TCP_Server_Info *server, struct mid_q_entry **mid)
|
|||||||
struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf;
|
struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf;
|
||||||
unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
|
unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
|
||||||
|
|
||||||
if (pdu_length + 4 < sizeof(struct smb2_transform_hdr) +
|
if (pdu_length + server->vals->header_preamble_size < sizeof(struct smb2_transform_hdr) +
|
||||||
sizeof(struct smb2_sync_hdr)) {
|
sizeof(struct smb2_sync_hdr)) {
|
||||||
cifs_dbg(VFS, "Transform message is too small (%u)\n",
|
cifs_dbg(VFS, "Transform message is too small (%u)\n",
|
||||||
pdu_length);
|
pdu_length);
|
||||||
@ -2674,14 +2681,14 @@ smb3_receive_transform(struct TCP_Server_Info *server, struct mid_q_entry **mid)
|
|||||||
return -ECONNABORTED;
|
return -ECONNABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdu_length + 4 < orig_len + sizeof(struct smb2_transform_hdr)) {
|
if (pdu_length + server->vals->header_preamble_size < orig_len + sizeof(struct smb2_transform_hdr)) {
|
||||||
cifs_dbg(VFS, "Transform message is broken\n");
|
cifs_dbg(VFS, "Transform message is broken\n");
|
||||||
cifs_reconnect(server);
|
cifs_reconnect(server);
|
||||||
wake_up(&server->response_q);
|
wake_up(&server->response_q);
|
||||||
return -ECONNABORTED;
|
return -ECONNABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdu_length + 4 > CIFSMaxBufSize + MAX_HEADER_SIZE(server))
|
if (pdu_length + server->vals->header_preamble_size > CIFSMaxBufSize + MAX_HEADER_SIZE(server))
|
||||||
return receive_encrypted_read(server, mid);
|
return receive_encrypted_read(server, mid);
|
||||||
|
|
||||||
return receive_encrypted_standard(server, mid);
|
return receive_encrypted_standard(server, mid);
|
||||||
@ -2692,7 +2699,8 @@ smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
{
|
{
|
||||||
char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
|
char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
|
||||||
|
|
||||||
return handle_read_data(server, mid, buf, get_rfc1002_length(buf) + 4,
|
return handle_read_data(server, mid, buf, get_rfc1002_length(buf) +
|
||||||
|
server->vals->header_preamble_size,
|
||||||
NULL, 0, 0);
|
NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3097,6 +3105,7 @@ struct smb_version_values smb20_values = {
|
|||||||
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
||||||
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
||||||
.header_size = sizeof(struct smb2_hdr),
|
.header_size = sizeof(struct smb2_hdr),
|
||||||
|
.header_preamble_size = 4,
|
||||||
.max_header_size = MAX_SMB2_HDR_SIZE,
|
.max_header_size = MAX_SMB2_HDR_SIZE,
|
||||||
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
||||||
.lock_cmd = SMB2_LOCK,
|
.lock_cmd = SMB2_LOCK,
|
||||||
@ -3117,6 +3126,7 @@ struct smb_version_values smb21_values = {
|
|||||||
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
||||||
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
||||||
.header_size = sizeof(struct smb2_hdr),
|
.header_size = sizeof(struct smb2_hdr),
|
||||||
|
.header_preamble_size = 4,
|
||||||
.max_header_size = MAX_SMB2_HDR_SIZE,
|
.max_header_size = MAX_SMB2_HDR_SIZE,
|
||||||
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
||||||
.lock_cmd = SMB2_LOCK,
|
.lock_cmd = SMB2_LOCK,
|
||||||
@ -3137,6 +3147,7 @@ struct smb_version_values smb3any_values = {
|
|||||||
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
||||||
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
||||||
.header_size = sizeof(struct smb2_hdr),
|
.header_size = sizeof(struct smb2_hdr),
|
||||||
|
.header_preamble_size = 4,
|
||||||
.max_header_size = MAX_SMB2_HDR_SIZE,
|
.max_header_size = MAX_SMB2_HDR_SIZE,
|
||||||
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
||||||
.lock_cmd = SMB2_LOCK,
|
.lock_cmd = SMB2_LOCK,
|
||||||
@ -3157,6 +3168,7 @@ struct smb_version_values smbdefault_values = {
|
|||||||
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
||||||
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
||||||
.header_size = sizeof(struct smb2_hdr),
|
.header_size = sizeof(struct smb2_hdr),
|
||||||
|
.header_preamble_size = 4,
|
||||||
.max_header_size = MAX_SMB2_HDR_SIZE,
|
.max_header_size = MAX_SMB2_HDR_SIZE,
|
||||||
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
||||||
.lock_cmd = SMB2_LOCK,
|
.lock_cmd = SMB2_LOCK,
|
||||||
@ -3177,6 +3189,7 @@ struct smb_version_values smb30_values = {
|
|||||||
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
||||||
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
||||||
.header_size = sizeof(struct smb2_hdr),
|
.header_size = sizeof(struct smb2_hdr),
|
||||||
|
.header_preamble_size = 4,
|
||||||
.max_header_size = MAX_SMB2_HDR_SIZE,
|
.max_header_size = MAX_SMB2_HDR_SIZE,
|
||||||
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
||||||
.lock_cmd = SMB2_LOCK,
|
.lock_cmd = SMB2_LOCK,
|
||||||
@ -3197,6 +3210,7 @@ struct smb_version_values smb302_values = {
|
|||||||
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
||||||
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
||||||
.header_size = sizeof(struct smb2_hdr),
|
.header_size = sizeof(struct smb2_hdr),
|
||||||
|
.header_preamble_size = 4,
|
||||||
.max_header_size = MAX_SMB2_HDR_SIZE,
|
.max_header_size = MAX_SMB2_HDR_SIZE,
|
||||||
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
||||||
.lock_cmd = SMB2_LOCK,
|
.lock_cmd = SMB2_LOCK,
|
||||||
@ -3218,6 +3232,7 @@ struct smb_version_values smb311_values = {
|
|||||||
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
|
||||||
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
|
||||||
.header_size = sizeof(struct smb2_hdr),
|
.header_size = sizeof(struct smb2_hdr),
|
||||||
|
.header_preamble_size = 4,
|
||||||
.max_header_size = MAX_SMB2_HDR_SIZE,
|
.max_header_size = MAX_SMB2_HDR_SIZE,
|
||||||
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
|
||||||
.lock_cmd = SMB2_LOCK,
|
.lock_cmd = SMB2_LOCK,
|
||||||
|
@ -1471,7 +1471,7 @@ parse_lease_state(struct TCP_Server_Info *server, struct smb2_create_rsp *rsp,
|
|||||||
unsigned int remaining;
|
unsigned int remaining;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset);
|
data_offset = (char *)rsp + server->vals->header_preamble_size + le32_to_cpu(rsp->CreateContextsOffset);
|
||||||
remaining = le32_to_cpu(rsp->CreateContextsLength);
|
remaining = le32_to_cpu(rsp->CreateContextsLength);
|
||||||
cc = (struct create_context *)data_offset;
|
cc = (struct create_context *)data_offset;
|
||||||
while (remaining >= sizeof(struct create_context)) {
|
while (remaining >= sizeof(struct create_context)) {
|
||||||
@ -3452,6 +3452,7 @@ static int
|
|||||||
build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level,
|
build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level,
|
||||||
int outbuf_len, u64 persistent_fid, u64 volatile_fid)
|
int outbuf_len, u64 persistent_fid, u64 volatile_fid)
|
||||||
{
|
{
|
||||||
|
struct TCP_Server_Info *server = tcon->ses->server;
|
||||||
int rc;
|
int rc;
|
||||||
struct smb2_query_info_req *req;
|
struct smb2_query_info_req *req;
|
||||||
unsigned int total_len;
|
unsigned int total_len;
|
||||||
@ -3474,7 +3475,7 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level,
|
|||||||
req->InputBufferOffset =
|
req->InputBufferOffset =
|
||||||
cpu_to_le16(sizeof(struct smb2_query_info_req) - 1);
|
cpu_to_le16(sizeof(struct smb2_query_info_req) - 1);
|
||||||
req->OutputBufferLength = cpu_to_le32(
|
req->OutputBufferLength = cpu_to_le32(
|
||||||
outbuf_len + sizeof(struct smb2_query_info_rsp) - 1 - 4);
|
outbuf_len + sizeof(struct smb2_query_info_rsp) - 1 - server->vals->header_preamble_size);
|
||||||
|
|
||||||
iov->iov_base = (char *)req;
|
iov->iov_base = (char *)req;
|
||||||
iov->iov_len = total_len;
|
iov->iov_len = total_len;
|
||||||
@ -3491,6 +3492,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
int resp_buftype;
|
int resp_buftype;
|
||||||
struct cifs_ses *ses = tcon->ses;
|
struct cifs_ses *ses = tcon->ses;
|
||||||
|
struct TCP_Server_Info *server = ses->server;
|
||||||
struct smb2_fs_full_size_info *info = NULL;
|
struct smb2_fs_full_size_info *info = NULL;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
@ -3511,7 +3513,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
}
|
}
|
||||||
rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
|
rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
|
||||||
|
|
||||||
info = (struct smb2_fs_full_size_info *)(4 /* RFC1001 len */ +
|
info = (struct smb2_fs_full_size_info *)(server->vals->header_preamble_size +
|
||||||
le16_to_cpu(rsp->OutputBufferOffset) + (char *)&rsp->hdr);
|
le16_to_cpu(rsp->OutputBufferOffset) + (char *)&rsp->hdr);
|
||||||
rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset),
|
rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset),
|
||||||
le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr,
|
le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr,
|
||||||
@ -3534,6 +3536,7 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
int resp_buftype, max_len, min_len;
|
int resp_buftype, max_len, min_len;
|
||||||
struct cifs_ses *ses = tcon->ses;
|
struct cifs_ses *ses = tcon->ses;
|
||||||
|
struct TCP_Server_Info *server = ses->server;
|
||||||
unsigned int rsp_len, offset;
|
unsigned int rsp_len, offset;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
@ -3574,15 +3577,15 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
goto qfsattr_exit;
|
goto qfsattr_exit;
|
||||||
|
|
||||||
if (level == FS_ATTRIBUTE_INFORMATION)
|
if (level == FS_ATTRIBUTE_INFORMATION)
|
||||||
memcpy(&tcon->fsAttrInfo, 4 /* RFC1001 len */ + offset
|
memcpy(&tcon->fsAttrInfo, server->vals->header_preamble_size + offset
|
||||||
+ (char *)&rsp->hdr, min_t(unsigned int,
|
+ (char *)&rsp->hdr, min_t(unsigned int,
|
||||||
rsp_len, max_len));
|
rsp_len, max_len));
|
||||||
else if (level == FS_DEVICE_INFORMATION)
|
else if (level == FS_DEVICE_INFORMATION)
|
||||||
memcpy(&tcon->fsDevInfo, 4 /* RFC1001 len */ + offset
|
memcpy(&tcon->fsDevInfo, server->vals->header_preamble_size + offset
|
||||||
+ (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO));
|
+ (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO));
|
||||||
else if (level == FS_SECTOR_SIZE_INFORMATION) {
|
else if (level == FS_SECTOR_SIZE_INFORMATION) {
|
||||||
struct smb3_fs_ss_info *ss_info = (struct smb3_fs_ss_info *)
|
struct smb3_fs_ss_info *ss_info = (struct smb3_fs_ss_info *)
|
||||||
(4 /* RFC1001 len */ + offset + (char *)&rsp->hdr);
|
(server->vals->header_preamble_size + offset + (char *)&rsp->hdr);
|
||||||
tcon->ss_flags = le32_to_cpu(ss_info->Flags);
|
tcon->ss_flags = le32_to_cpu(ss_info->Flags);
|
||||||
tcon->perf_sector_size =
|
tcon->perf_sector_size =
|
||||||
le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf);
|
le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf);
|
||||||
|
@ -790,7 +790,8 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
|||||||
|
|
||||||
buf = (char *)midQ->resp_buf;
|
buf = (char *)midQ->resp_buf;
|
||||||
resp_iov->iov_base = buf;
|
resp_iov->iov_base = buf;
|
||||||
resp_iov->iov_len = get_rfc1002_length(buf) + 4;
|
resp_iov->iov_len = get_rfc1002_length(buf) +
|
||||||
|
ses->server->vals->header_preamble_size;
|
||||||
if (midQ->large_buf)
|
if (midQ->large_buf)
|
||||||
*resp_buf_type = CIFS_LARGE_BUFFER;
|
*resp_buf_type = CIFS_LARGE_BUFFER;
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user