aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorIngo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>2014-02-05 06:29:57 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-02-12 03:49:45 -0500
commit63ef79c25b5bbd356d04ef93d15693d8664c6141 (patch)
tree54e737cf49c58399ddbff264fe719297a49af42e /drivers/s390
parent45f7fdc2ffb9d5af4dab593843e89da70d1259e3 (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')
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype6.c24
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));