cifs: update calc_size to take a server argument
and change the smb2 version to take heder_preamble_size into account instead of hardcoding it as 4 bytes. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
parent
14547f7d74
commit
9ec672bd17
|
@ -372,7 +372,7 @@ struct smb_version_operations {
|
||||||
int (*close_dir)(const unsigned int, struct cifs_tcon *,
|
int (*close_dir)(const unsigned int, struct cifs_tcon *,
|
||||||
struct cifs_fid *);
|
struct cifs_fid *);
|
||||||
/* calculate a size of SMB message */
|
/* calculate a size of SMB message */
|
||||||
unsigned int (*calc_smb_size)(void *);
|
unsigned int (*calc_smb_size)(void *buf, struct TCP_Server_Info *ptcpi);
|
||||||
/* check for STATUS_PENDING and process it in a positive case */
|
/* check for STATUS_PENDING and process it in a positive case */
|
||||||
bool (*is_status_pending)(char *, struct TCP_Server_Info *, int);
|
bool (*is_status_pending)(char *, struct TCP_Server_Info *, int);
|
||||||
/* check for STATUS_NETWORK_SESSION_EXPIRED */
|
/* check for STATUS_NETWORK_SESSION_EXPIRED */
|
||||||
|
|
|
@ -124,7 +124,7 @@ extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
|
||||||
unsigned int bytes_written);
|
unsigned int bytes_written);
|
||||||
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
|
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
|
||||||
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
|
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
|
||||||
extern unsigned int smbCalcSize(void *buf);
|
extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server);
|
||||||
extern int decode_negTokenInit(unsigned char *security_blob, int length,
|
extern int decode_negTokenInit(unsigned char *security_blob, int length,
|
||||||
struct TCP_Server_Info *server);
|
struct TCP_Server_Info *server);
|
||||||
extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
|
extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
|
||||||
|
|
|
@ -342,7 +342,7 @@ checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server)
|
||||||
/* otherwise, there is enough to get to the BCC */
|
/* otherwise, there is enough to get to the BCC */
|
||||||
if (check_smb_hdr(smb))
|
if (check_smb_hdr(smb))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
clc_len = smbCalcSize(smb);
|
clc_len = smbCalcSize(smb, server);
|
||||||
|
|
||||||
if (4 + rfclen != total_read) {
|
if (4 + rfclen != total_read) {
|
||||||
cifs_dbg(VFS, "Length read does not match RFC1001 length %d\n",
|
cifs_dbg(VFS, "Length read does not match RFC1001 length %d\n",
|
||||||
|
|
|
@ -903,7 +903,7 @@ map_smb_to_linux_error(char *buf, bool logErr)
|
||||||
* portion, the number of word parameters and the data portion of the message
|
* portion, the number of word parameters and the data portion of the message
|
||||||
*/
|
*/
|
||||||
unsigned int
|
unsigned int
|
||||||
smbCalcSize(void *buf)
|
smbCalcSize(void *buf, struct TCP_Server_Info *server)
|
||||||
{
|
{
|
||||||
struct smb_hdr *ptr = (struct smb_hdr *)buf;
|
struct smb_hdr *ptr = (struct smb_hdr *)buf;
|
||||||
return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
|
return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
|
||||||
|
|
|
@ -650,7 +650,8 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
|
||||||
char *cur_ent;
|
char *cur_ent;
|
||||||
char *end_of_smb = cfile->srch_inf.ntwrk_buf_start +
|
char *end_of_smb = cfile->srch_inf.ntwrk_buf_start +
|
||||||
server->ops->calc_smb_size(
|
server->ops->calc_smb_size(
|
||||||
cfile->srch_inf.ntwrk_buf_start);
|
cfile->srch_inf.ntwrk_buf_start,
|
||||||
|
server);
|
||||||
|
|
||||||
cur_ent = cfile->srch_inf.srch_entries_start;
|
cur_ent = cfile->srch_inf.srch_entries_start;
|
||||||
first_entry_in_buffer = cfile->srch_inf.index_of_last_entry
|
first_entry_in_buffer = cfile->srch_inf.index_of_last_entry
|
||||||
|
@ -831,7 +832,8 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
|
||||||
cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",
|
cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",
|
||||||
num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
|
num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
|
||||||
max_len = tcon->ses->server->ops->calc_smb_size(
|
max_len = tcon->ses->server->ops->calc_smb_size(
|
||||||
cifsFile->srch_inf.ntwrk_buf_start);
|
cifsFile->srch_inf.ntwrk_buf_start,
|
||||||
|
tcon->ses->server);
|
||||||
end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
|
end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
|
||||||
|
|
||||||
tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
|
tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
|
||||||
|
|
|
@ -233,7 +233,7 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
clc_len = smb2_calc_size(hdr);
|
clc_len = smb2_calc_size(hdr, srvr);
|
||||||
|
|
||||||
#ifdef CONFIG_CIFS_SMB311
|
#ifdef CONFIG_CIFS_SMB311
|
||||||
if (shdr->Command == SMB2_NEGOTIATE)
|
if (shdr->Command == SMB2_NEGOTIATE)
|
||||||
|
@ -403,7 +403,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
|
||||||
* portion, the number of word parameters and the data portion of the message.
|
* portion, the number of word parameters and the data portion of the message.
|
||||||
*/
|
*/
|
||||||
unsigned int
|
unsigned int
|
||||||
smb2_calc_size(void *buf)
|
smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
|
||||||
{
|
{
|
||||||
struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
|
struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
|
||||||
struct smb2_hdr *hdr = &pdu->hdr;
|
struct smb2_hdr *hdr = &pdu->hdr;
|
||||||
|
@ -411,7 +411,7 @@ smb2_calc_size(void *buf)
|
||||||
int offset; /* the offset from the beginning of SMB to data area */
|
int offset; /* the offset from the beginning of SMB to data area */
|
||||||
int data_length; /* the length of the variable length data area */
|
int data_length; /* the length of the variable length data area */
|
||||||
/* Structure Size has already been checked to make sure it is 64 */
|
/* Structure Size has already been checked to make sure it is 64 */
|
||||||
int len = 4 + le16_to_cpu(shdr->StructureSize);
|
int len = srvr->vals->header_preamble_size + le16_to_cpu(shdr->StructureSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* StructureSize2, ie length of fixed parameter area has already
|
* StructureSize2, ie length of fixed parameter area has already
|
||||||
|
@ -433,12 +433,12 @@ smb2_calc_size(void *buf)
|
||||||
* so we must add one to the calculation (and 4 to account for
|
* so we must add one to the calculation (and 4 to account for
|
||||||
* the size of the RFC1001 hdr.
|
* the size of the RFC1001 hdr.
|
||||||
*/
|
*/
|
||||||
if (offset + 4 + 1 < len) {
|
if (offset + srvr->vals->header_preamble_size + 1 < len) {
|
||||||
cifs_dbg(VFS, "data area offset %d overlaps SMB2 header %d\n",
|
cifs_dbg(VFS, "data area offset %zu overlaps SMB2 header %d\n",
|
||||||
offset + 4 + 1, len);
|
offset + srvr->vals->header_preamble_size + 1, len);
|
||||||
data_length = 0;
|
data_length = 0;
|
||||||
} else {
|
} else {
|
||||||
len = 4 + offset + data_length;
|
len = srvr->vals->header_preamble_size + offset + data_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
calc_size_exit:
|
calc_size_exit:
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct smb_rqst;
|
||||||
extern int map_smb2_to_linux_error(char *buf, bool log_err);
|
extern int map_smb2_to_linux_error(char *buf, bool log_err);
|
||||||
extern int smb2_check_message(char *buf, unsigned int length,
|
extern int smb2_check_message(char *buf, unsigned int length,
|
||||||
struct TCP_Server_Info *server);
|
struct TCP_Server_Info *server);
|
||||||
extern unsigned int smb2_calc_size(void *buf);
|
extern unsigned int smb2_calc_size(void *buf, struct TCP_Server_Info *server);
|
||||||
extern char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr);
|
extern char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr);
|
||||||
extern __le16 *cifs_convert_path_to_utf16(const char *from,
|
extern __le16 *cifs_convert_path_to_utf16(const char *from,
|
||||||
struct cifs_sb_info *cifs_sb);
|
struct cifs_sb_info *cifs_sb);
|
||||||
|
|
Loading…
Reference in New Issue