s390/zcrypt: add length check for aligned data to avoid overflow in msg-type 6
authorIngo Tuchscherer <ingo.tuchscherer@de.ibm.com>
Tue, 18 Mar 2014 15:30:21 +0000 (16:30 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 1 Apr 2014 07:23:34 +0000 (09:23 +0200)
Signed-off-by: Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_msgtype6.c

index 4b824b15194f6eb034c4dd2ef4a7f0ab3ee9c3b7..5222ebe15705e14f8a0a9b2598b63ebb3672752f 100644 (file)
@@ -626,8 +626,8 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
                        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;
        }
index 0bc91e46395a8d84ad8c989b6d2a7844593c3ba0..46b324ce6c7a8d46fe335b6b994db455e7c3beb8 100644 (file)
@@ -315,6 +315,10 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
        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 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
                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 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(struct zcrypt_device *zdev,
                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 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(struct zcrypt_device *zdev,
 
        /* 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 @@ static int convert_type86_ep11_xcrb(struct zcrypt_device *zdev,
                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;
This page took 0.02803 seconds and 5 git commands to generate.