s390/zcrypt: add length check for aligned data to avoid overflow in msg-type 6

Signed-off-by: Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 4b824b1..5222ebe 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -626,8 +626,8 @@
 			return -ENOMEM;
 
 		if (copy_from_user(ep11_dev_list.targets,
-				   (struct ep11_target_dev *)xcrb->targets,
-				   xcrb->targets_num *
+				   (struct ep11_target_dev __force __user *)
+				   xcrb->targets, xcrb->targets_num *
 				   sizeof(struct ep11_target_dev)))
 			return -EFAULT;
 	}
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 0bc91e4..46b324c 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -315,6 +315,10 @@
 	char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
 	char *function_code;
 
+	if (CEIL4(xcRB->request_control_blk_length) <
+			xcRB->request_control_blk_length)
+		return -EINVAL; /* overflow after alignment*/
+
 	/* length checks */
 	ap_msg->length = sizeof(struct type6_hdr) +
 		CEIL4(xcRB->request_control_blk_length) +
@@ -333,6 +337,10 @@
 		return -EINVAL;
 	}
 
+	if (CEIL4(xcRB->reply_control_blk_length) <
+			xcRB->reply_control_blk_length)
+		return -EINVAL; /* overflow after alignment*/
+
 	replylen = sizeof(struct type86_fmt2_msg) +
 		CEIL4(xcRB->reply_control_blk_length) +
 		xcRB->reply_data_length;
@@ -415,12 +423,18 @@
 		unsigned int	dom_val;	/* domain id	   */
 	} __packed * payload_hdr;
 
+	if (CEIL4(xcRB->req_len) < xcRB->req_len)
+		return -EINVAL; /* overflow after alignment*/
+
 	/* length checks */
 	ap_msg->length = sizeof(struct type6_hdr) + xcRB->req_len;
 	if (CEIL4(xcRB->req_len) > MSGTYPE06_MAX_MSG_SIZE -
 				   (sizeof(struct type6_hdr)))
 		return -EINVAL;
 
+	if (CEIL4(xcRB->resp_len) < xcRB->resp_len)
+		return -EINVAL; /* overflow after alignment*/
+
 	if (CEIL4(xcRB->resp_len) > MSGTYPE06_MAX_MSG_SIZE -
 				    (sizeof(struct type86_fmt2_msg)))
 		return -EINVAL;
@@ -432,7 +446,7 @@
 
 	/* Import CPRB data from the ioctl input parameter */
 	if (copy_from_user(&(msg->cprbx.cprb_len),
-			   (char *)xcRB->req, xcRB->req_len)) {
+			   (char __force __user *)xcRB->req, xcRB->req_len)) {
 		return -EFAULT;
 	}
 
@@ -645,7 +659,7 @@
 		return -EINVAL;
 
 	/* Copy response CPRB to user */
-	if (copy_to_user((char *)xcRB->resp,
+	if (copy_to_user((char __force __user *)xcRB->resp,
 			 data + msg->fmt2.offset1, msg->fmt2.count1))
 		return -EFAULT;
 	xcRB->resp_len = msg->fmt2.count1;