summaryrefslogtreecommitdiff
path: root/drivers/s390/crypto/zcrypt_api.c
diff options
context:
space:
mode:
authorHarald Freudenberger <freude@de.ibm.com>2018-05-28 14:00:42 +0300
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-05-30 12:18:05 +0300
commit89a0c0ec0d2e3ce0ee9caa00f60c0c26ccf11c21 (patch)
tree7e784683c6cb778d43b8b7fb4b3e73a78c19e533 /drivers/s390/crypto/zcrypt_api.c
parent966f53e750aedc5f59f9ccae6bbfb8f671c7c842 (diff)
downloadlinux-89a0c0ec0d2e3ce0ee9caa00f60c0c26ccf11c21.tar.xz
s390/zcrypt: Fix CCA and EP11 CPRB processing failure memory leak.
Tests showed, that the zcrypt device driver produces memory leaks when a valid CCA or EP11 CPRB can't get delivered or has a failure during processing within the zcrypt device driver. This happens when a invalid domain or adapter number is used or the lower level software or hardware layers produce any kind of failure during processing of the request. Only CPRBs send to CCA or EP11 cards can produce this memory leak. The accelerator and the CPRBs processed by this type of crypto card is not affected. The two fields message and private within the ap_message struct are allocated with pulling the function code for the CPRB but only freed when processing of the CPRB succeeds. So for example an invalid domain or adapter field causes the processing to fail, leaving these two memory areas allocated forever. Signed-off-by: Harald Freudenberger <freude@de.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto/zcrypt_api.c')
-rw-r--r--drivers/s390/crypto/zcrypt_api.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 5efd84862ccb..febcdb5135bf 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -371,6 +371,7 @@ long zcrypt_send_cprb(struct ica_xcRB *xcRB)
trace_s390_zcrypt_req(xcRB, TB_ZSECSENDCPRB);
+ ap_init_message(&ap_msg);
rc = get_cprb_fc(xcRB, &ap_msg, &func_code, &domain);
if (rc)
goto out;
@@ -425,6 +426,7 @@ long zcrypt_send_cprb(struct ica_xcRB *xcRB)
spin_unlock(&zcrypt_list_lock);
out:
+ ap_release_message(&ap_msg);
trace_s390_zcrypt_rep(xcRB, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;
@@ -468,6 +470,8 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB);
+ ap_init_message(&ap_msg);
+
target_num = (unsigned short) xcrb->targets_num;
/* empty list indicates autoselect (all available targets) */
@@ -485,7 +489,7 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
if (copy_from_user(targets, uptr,
target_num * sizeof(*targets))) {
rc = -EFAULT;
- goto out;
+ goto out_free;
}
}
@@ -542,6 +546,7 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
out_free:
kfree(targets);
out:
+ ap_release_message(&ap_msg);
trace_s390_zcrypt_rep(xcrb, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;
@@ -559,6 +564,7 @@ static long zcrypt_rng(char *buffer)
trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB);
+ ap_init_message(&ap_msg);
rc = get_rng_fc(&ap_msg, &func_code, &domain);
if (rc)
goto out;
@@ -589,8 +595,10 @@ static long zcrypt_rng(char *buffer)
pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, weight);
spin_unlock(&zcrypt_list_lock);
- if (!pref_zq)
- return -ENODEV;
+ if (!pref_zq) {
+ rc = -ENODEV;
+ goto out;
+ }
qid = pref_zq->queue->qid;
rc = pref_zq->ops->rng(pref_zq, buffer, &ap_msg);
@@ -600,6 +608,7 @@ static long zcrypt_rng(char *buffer)
spin_unlock(&zcrypt_list_lock);
out:
+ ap_release_message(&ap_msg);
trace_s390_zcrypt_rep(buffer, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;