diff options
author | Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com> | 2014-03-18 11:30:21 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-04-01 03:23:34 -0400 |
commit | ce1ce2f31224c18e84d859ccd5675cbb2728f57a (patch) | |
tree | eebcf330a28c9f39a214443ec575330588c61454 /drivers/s390 | |
parent | 01d5f3b598b18a5035426c30801adf65822dbd0c (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.c | 4 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_msgtype6.c | 18 |
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; |