diff options
| author | Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com> | 2014-02-05 06:29:57 -0500 |
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-02-12 03:49:45 -0500 |
| commit | 63ef79c25b5bbd356d04ef93d15693d8664c6141 (patch) | |
| tree | 54e737cf49c58399ddbff264fe719297a49af42e /drivers/s390/crypto | |
| parent | 45f7fdc2ffb9d5af4dab593843e89da70d1259e3 (diff) | |
s390/zcrypt: additional check to avoid overflow in msg-type 6 requests
Signed-off-by: Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto')
| -rw-r--r-- | drivers/s390/crypto/zcrypt_msgtype6.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c index dc542e0a3055..0bc91e46395a 100644 --- a/drivers/s390/crypto/zcrypt_msgtype6.c +++ b/drivers/s390/crypto/zcrypt_msgtype6.c | |||
| @@ -311,7 +311,7 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
| 311 | } __packed * msg = ap_msg->message; | 311 | } __packed * msg = ap_msg->message; |
| 312 | 312 | ||
| 313 | int rcblen = CEIL4(xcRB->request_control_blk_length); | 313 | int rcblen = CEIL4(xcRB->request_control_blk_length); |
| 314 | int replylen; | 314 | int replylen, req_sumlen, resp_sumlen; |
| 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 | ||
| @@ -321,12 +321,34 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
| 321 | xcRB->request_data_length; | 321 | xcRB->request_data_length; |
| 322 | if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE) | 322 | if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE) |
| 323 | return -EINVAL; | 323 | return -EINVAL; |
| 324 | |||
| 325 | /* Overflow check | ||
| 326 | sum must be greater (or equal) than the largest operand */ | ||
| 327 | req_sumlen = CEIL4(xcRB->request_control_blk_length) + | ||
| 328 | xcRB->request_data_length; | ||
| 329 | if ((CEIL4(xcRB->request_control_blk_length) <= | ||
| 330 | xcRB->request_data_length) ? | ||
| 331 | (req_sumlen < xcRB->request_data_length) : | ||
| 332 | (req_sumlen < CEIL4(xcRB->request_control_blk_length))) { | ||
| 333 | return -EINVAL; | ||
| 334 | } | ||
| 335 | |||
| 324 | replylen = sizeof(struct type86_fmt2_msg) + | 336 | replylen = sizeof(struct type86_fmt2_msg) + |
| 325 | CEIL4(xcRB->reply_control_blk_length) + | 337 | CEIL4(xcRB->reply_control_blk_length) + |
| 326 | xcRB->reply_data_length; | 338 | xcRB->reply_data_length; |
| 327 | if (replylen > MSGTYPE06_MAX_MSG_SIZE) | 339 | if (replylen > MSGTYPE06_MAX_MSG_SIZE) |
| 328 | return -EINVAL; | 340 | return -EINVAL; |
| 329 | 341 | ||
| 342 | /* Overflow check | ||
| 343 | sum must be greater (or equal) than the largest operand */ | ||
| 344 | resp_sumlen = CEIL4(xcRB->reply_control_blk_length) + | ||
| 345 | xcRB->reply_data_length; | ||
| 346 | if ((CEIL4(xcRB->reply_control_blk_length) <= xcRB->reply_data_length) ? | ||
| 347 | (resp_sumlen < xcRB->reply_data_length) : | ||
| 348 | (resp_sumlen < CEIL4(xcRB->reply_control_blk_length))) { | ||
| 349 | return -EINVAL; | ||
| 350 | } | ||
| 351 | |||
| 330 | /* prepare type6 header */ | 352 | /* prepare type6 header */ |
| 331 | msg->hdr = static_type6_hdrX; | 353 | msg->hdr = static_type6_hdrX; |
| 332 | memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID)); | 354 | memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID)); |
