diff options
Diffstat (limited to 'fs/smb/server/smb2misc.c')
| -rw-r--r-- | fs/smb/server/smb2misc.c | 26 | 
1 files changed, 19 insertions, 7 deletions
diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c index 03dded29a980..727cb49926ee 100644 --- a/fs/smb/server/smb2misc.c +++ b/fs/smb/server/smb2misc.c @@ -101,13 +101,17 @@ static int smb2_get_data_area_len(unsigned int *off, unsigned int *len,  		*len = le16_to_cpu(((struct smb2_sess_setup_req *)hdr)->SecurityBufferLength);  		break;  	case SMB2_TREE_CONNECT: -		*off = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathOffset); +		*off = max_t(unsigned short int, +			     le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathOffset), +			     offsetof(struct smb2_tree_connect_req, Buffer));  		*len = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathLength);  		break;  	case SMB2_CREATE:  	{  		unsigned short int name_off = -			le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset); +			max_t(unsigned short int, +			      le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset), +			      offsetof(struct smb2_create_req, Buffer));  		unsigned short int name_len =  			le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength); @@ -128,11 +132,15 @@ static int smb2_get_data_area_len(unsigned int *off, unsigned int *len,  		break;  	}  	case SMB2_QUERY_INFO: -		*off = le16_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferOffset); +		*off = max_t(unsigned int, +			     le16_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferOffset), +			     offsetof(struct smb2_query_info_req, Buffer));  		*len = le32_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferLength);  		break;  	case SMB2_SET_INFO: -		*off = le16_to_cpu(((struct smb2_set_info_req *)hdr)->BufferOffset); +		*off = max_t(unsigned int, +			     le16_to_cpu(((struct smb2_set_info_req *)hdr)->BufferOffset), +			     offsetof(struct smb2_set_info_req, Buffer));  		*len = le32_to_cpu(((struct smb2_set_info_req *)hdr)->BufferLength);  		break;  	case SMB2_READ: @@ -142,7 +150,7 @@ static int smb2_get_data_area_len(unsigned int *off, unsigned int *len,  	case SMB2_WRITE:  		if (((struct smb2_write_req *)hdr)->DataOffset ||  		    ((struct smb2_write_req *)hdr)->Length) { -			*off = max_t(unsigned int, +			*off = max_t(unsigned short int,  				     le16_to_cpu(((struct smb2_write_req *)hdr)->DataOffset),  				     offsetof(struct smb2_write_req, Buffer));  			*len = le32_to_cpu(((struct smb2_write_req *)hdr)->Length); @@ -153,7 +161,9 @@ static int smb2_get_data_area_len(unsigned int *off, unsigned int *len,  		*len = le16_to_cpu(((struct smb2_write_req *)hdr)->WriteChannelInfoLength);  		break;  	case SMB2_QUERY_DIRECTORY: -		*off = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameOffset); +		*off = max_t(unsigned short int, +			     le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameOffset), +			     offsetof(struct smb2_query_directory_req, Buffer));  		*len = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameLength);  		break;  	case SMB2_LOCK: @@ -168,7 +178,9 @@ static int smb2_get_data_area_len(unsigned int *off, unsigned int *len,  		break;  	}  	case SMB2_IOCTL: -		*off = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputOffset); +		*off = max_t(unsigned int, +			     le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputOffset), +			     offsetof(struct smb2_ioctl_req, Buffer));  		*len = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputCount);  		break;  	default:  |