diff options
Diffstat (limited to 'fs/smb/server/smb2pdu.c')
| -rw-r--r-- | fs/smb/server/smb2pdu.c | 22 | 
1 files changed, 16 insertions, 6 deletions
| diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 37a39ab4ee65..0bc9edf22ba4 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -1370,7 +1370,8 @@ static int ntlm_negotiate(struct ksmbd_work *work,  	}  	sz = le16_to_cpu(rsp->SecurityBufferOffset); -	memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len); +	unsafe_memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len, +			/* alloc is larger than blob, see smb2_allocate_rsp_buf() */);  	rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);  out: @@ -1453,7 +1454,9 @@ static int ntlm_authenticate(struct ksmbd_work *work,  			return -ENOMEM;  		sz = le16_to_cpu(rsp->SecurityBufferOffset); -		memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len); +		unsafe_memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, +				spnego_blob_len, +				/* alloc is larger than blob, see smb2_allocate_rsp_buf() */);  		rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);  		kfree(spnego_blob);  	} @@ -1955,7 +1958,7 @@ int smb2_tree_connect(struct ksmbd_work *work)  	ksmbd_debug(SMB, "tree connect request for tree %s treename %s\n",  		    name, treename); -	status = ksmbd_tree_conn_connect(conn, sess, name); +	status = ksmbd_tree_conn_connect(work, name);  	if (status.ret == KSMBD_TREE_CONN_STATUS_OK)  		rsp->hdr.Id.SyncId.TreeId = cpu_to_le32(status.tree_conn->id);  	else @@ -2210,7 +2213,7 @@ int smb2_session_logoff(struct ksmbd_work *work)  	ksmbd_conn_unlock(conn);  	ksmbd_close_session_fds(work); -	ksmbd_conn_wait_idle(conn, sess_id); +	ksmbd_conn_wait_idle(conn);  	/*  	 * Re-lookup session to validate if session is deleted @@ -5357,7 +5360,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,  					"NTFS", PATH_MAX, conn->local_nls, 0);  		len = len * 2;  		info->FileSystemNameLen = cpu_to_le32(len); -		sz = sizeof(struct filesystem_attribute_info) - 2 + len; +		sz = sizeof(struct filesystem_attribute_info) + len;  		rsp->OutputBufferLength = cpu_to_le32(sz);  		break;  	} @@ -5383,7 +5386,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,  		len = len * 2;  		info->VolumeLabelSize = cpu_to_le32(len);  		info->Reserved = 0; -		sz = sizeof(struct filesystem_vol_info) - 2 + len; +		sz = sizeof(struct filesystem_vol_info) + len;  		rsp->OutputBufferLength = cpu_to_le32(sz);  		break;  	} @@ -5596,6 +5599,11 @@ int smb2_query_info(struct ksmbd_work *work)  	ksmbd_debug(SMB, "GOT query info request\n"); +	if (ksmbd_override_fsids(work)) { +		rc = -ENOMEM; +		goto err_out; +	} +  	switch (req->InfoType) {  	case SMB2_O_INFO_FILE:  		ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n"); @@ -5614,6 +5622,7 @@ int smb2_query_info(struct ksmbd_work *work)  			    req->InfoType);  		rc = -EOPNOTSUPP;  	} +	ksmbd_revert_fsids(work);  	if (!rc) {  		rsp->StructureSize = cpu_to_le16(9); @@ -5623,6 +5632,7 @@ int smb2_query_info(struct ksmbd_work *work)  					le32_to_cpu(rsp->OutputBufferLength));  	} +err_out:  	if (rc < 0) {  		if (rc == -EACCES)  			rsp->hdr.Status = STATUS_ACCESS_DENIED; |