aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorIngo Tuchscherer <ingo.tuchscherer@de.ibm.com>2014-03-18 11:30:21 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-04-01 03:23:34 -0400
commitce1ce2f31224c18e84d859ccd5675cbb2728f57a (patch)
treeeebcf330a28c9f39a214443ec575330588c61454 /drivers/s390
parent01d5f3b598b18a5035426c30801adf65822dbd0c (diff)
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>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/crypto/zcrypt_api.c4
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype6.c18
2 files changed, 18 insertions, 4 deletions
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 4b824b15194f..5222ebe15705 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -626,8 +626,8 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
626 return -ENOMEM; 626 return -ENOMEM;
627 627
628 if (copy_from_user(ep11_dev_list.targets, 628 if (copy_from_user(ep11_dev_list.targets,
629 (struct ep11_target_dev *)xcrb->targets, 629 (struct ep11_target_dev __force __user *)
630 xcrb->targets_num * 630 xcrb->targets, xcrb->targets_num *
631 sizeof(struct ep11_target_dev))) 631 sizeof(struct ep11_target_dev)))
632 return -EFAULT; 632 return -EFAULT;
633 } 633 }
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 0bc91e46395a..46b324ce6c7a 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -315,6 +315,10 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
315 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen; 315 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
316 char *function_code; 316 char *function_code;
317 317
318 if (CEIL4(xcRB->request_control_blk_length) <
319 xcRB->request_control_blk_length)
320 return -EINVAL; /* overflow after alignment*/
321
318 /* length checks */ 322 /* length checks */
319 ap_msg->length = sizeof(struct type6_hdr) + 323 ap_msg->length = sizeof(struct type6_hdr) +
320 CEIL4(xcRB->request_control_blk_length) + 324 CEIL4(xcRB->request_control_blk_length) +
@@ -333,6 +337,10 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
333 return -EINVAL; 337 return -EINVAL;
334 } 338 }
335 339
340 if (CEIL4(xcRB->reply_control_blk_length) <
341 xcRB->reply_control_blk_length)
342 return -EINVAL; /* overflow after alignment*/
343
336 replylen = sizeof(struct type86_fmt2_msg) + 344 replylen = sizeof(struct type86_fmt2_msg) +
337 CEIL4(xcRB->reply_control_blk_length) + 345 CEIL4(xcRB->reply_control_blk_length) +
338 xcRB->reply_data_length; 346 xcRB->reply_data_length;
@@ -415,12 +423,18 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(struct zcrypt_device *zdev,
415 unsigned int dom_val; /* domain id */ 423 unsigned int dom_val; /* domain id */
416 } __packed * payload_hdr; 424 } __packed * payload_hdr;
417 425
426 if (CEIL4(xcRB->req_len) < xcRB->req_len)
427 return -EINVAL; /* overflow after alignment*/
428
418 /* length checks */ 429 /* length checks */
419 ap_msg->length = sizeof(struct type6_hdr) + xcRB->req_len; 430 ap_msg->length = sizeof(struct type6_hdr) + xcRB->req_len;
420 if (CEIL4(xcRB->req_len) > MSGTYPE06_MAX_MSG_SIZE - 431 if (CEIL4(xcRB->req_len) > MSGTYPE06_MAX_MSG_SIZE -
421 (sizeof(struct type6_hdr))) 432 (sizeof(struct type6_hdr)))
422 return -EINVAL; 433 return -EINVAL;
423 434
435 if (CEIL4(xcRB->resp_len) < xcRB->resp_len)
436 return -EINVAL; /* overflow after alignment*/
437
424 if (CEIL4(xcRB->resp_len) > MSGTYPE06_MAX_MSG_SIZE - 438 if (CEIL4(xcRB->resp_len) > MSGTYPE06_MAX_MSG_SIZE -
425 (sizeof(struct type86_fmt2_msg))) 439 (sizeof(struct type86_fmt2_msg)))
426 return -EINVAL; 440 return -EINVAL;
@@ -432,7 +446,7 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(struct zcrypt_device *zdev,
432 446
433 /* Import CPRB data from the ioctl input parameter */ 447 /* Import CPRB data from the ioctl input parameter */
434 if (copy_from_user(&(msg->cprbx.cprb_len), 448 if (copy_from_user(&(msg->cprbx.cprb_len),
435 (char *)xcRB->req, xcRB->req_len)) { 449 (char __force __user *)xcRB->req, xcRB->req_len)) {
436 return -EFAULT; 450 return -EFAULT;
437 } 451 }
438 452
@@ -645,7 +659,7 @@ static int convert_type86_ep11_xcrb(struct zcrypt_device *zdev,
645 return -EINVAL; 659 return -EINVAL;
646 660
647 /* Copy response CPRB to user */ 661 /* Copy response CPRB to user */
648 if (copy_to_user((char *)xcRB->resp, 662 if (copy_to_user((char __force __user *)xcRB->resp,
649 data + msg->fmt2.offset1, msg->fmt2.count1)) 663 data + msg->fmt2.offset1, msg->fmt2.count1))
650 return -EFAULT; 664 return -EFAULT;
651 xcRB->resp_len = msg->fmt2.count1; 665 xcRB->resp_len = msg->fmt2.count1;