diff options
Diffstat (limited to 'drivers/s390/crypto')
-rw-r--r-- | drivers/s390/crypto/pkey_api.c | 109 |
1 files changed, 51 insertions, 58 deletions
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index dccf664a3d..ffc0b5db55 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -1359,10 +1359,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, rc = cca_genseckey(kgs.cardnr, kgs.domain, kgs.keytype, kgs.seckey.seckey); pr_debug("%s cca_genseckey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(ugs, &kgs, sizeof(kgs))) - return -EFAULT; + if (!rc && copy_to_user(ugs, &kgs, sizeof(kgs))) + rc = -EFAULT; + memzero_explicit(&kgs, sizeof(kgs)); break; } case PKEY_CLR2SECK: { @@ -1374,10 +1373,8 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, rc = cca_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype, kcs.clrkey.clrkey, kcs.seckey.seckey); pr_debug("%s cca_clr2seckey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(ucs, &kcs, sizeof(kcs))) - return -EFAULT; + if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs))) + rc = -EFAULT; memzero_explicit(&kcs, sizeof(kcs)); break; } @@ -1392,10 +1389,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, ksp.seckey.seckey, ksp.protkey.protkey, &ksp.protkey.len, &ksp.protkey.type); pr_debug("%s cca_sec2protkey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(usp, &ksp, sizeof(ksp))) - return -EFAULT; + if (!rc && copy_to_user(usp, &ksp, sizeof(ksp))) + rc = -EFAULT; + memzero_explicit(&ksp, sizeof(ksp)); break; } case PKEY_CLR2PROTK: { @@ -1409,10 +1405,8 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, kcp.protkey.protkey, &kcp.protkey.len, &kcp.protkey.type); pr_debug("%s pkey_clr2protkey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(ucp, &kcp, sizeof(kcp))) - return -EFAULT; + if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp))) + rc = -EFAULT; memzero_explicit(&kcp, sizeof(kcp)); break; } @@ -1441,10 +1435,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, rc = pkey_skey2pkey(ksp.seckey.seckey, ksp.protkey.protkey, &ksp.protkey.len, &ksp.protkey.type); pr_debug("%s pkey_skey2pkey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(usp, &ksp, sizeof(ksp))) - return -EFAULT; + if (!rc && copy_to_user(usp, &ksp, sizeof(ksp))) + rc = -EFAULT; + memzero_explicit(&ksp, sizeof(ksp)); break; } case PKEY_VERIFYKEY: { @@ -1456,10 +1449,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, rc = pkey_verifykey(&kvk.seckey, &kvk.cardnr, &kvk.domain, &kvk.keysize, &kvk.attributes); pr_debug("%s pkey_verifykey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(uvk, &kvk, sizeof(kvk))) - return -EFAULT; + if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk))) + rc = -EFAULT; + memzero_explicit(&kvk, sizeof(kvk)); break; } case PKEY_GENPROTK: { @@ -1472,10 +1464,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, rc = pkey_genprotkey(kgp.keytype, kgp.protkey.protkey, &kgp.protkey.len, &kgp.protkey.type); pr_debug("%s pkey_genprotkey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(ugp, &kgp, sizeof(kgp))) - return -EFAULT; + if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp))) + rc = -EFAULT; + memzero_explicit(&kgp, sizeof(kgp)); break; } case PKEY_VERIFYPROTK: { @@ -1487,6 +1478,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, rc = pkey_verifyprotkey(kvp.protkey.protkey, kvp.protkey.len, kvp.protkey.type); pr_debug("%s pkey_verifyprotkey()=%d\n", __func__, rc); + memzero_explicit(&kvp, sizeof(kvp)); break; } case PKEY_KBLOB2PROTK: { @@ -1503,12 +1495,10 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, rc = pkey_keyblob2pkey(kkey, ktp.keylen, ktp.protkey.protkey, &ktp.protkey.len, &ktp.protkey.type); pr_debug("%s pkey_keyblob2pkey()=%d\n", __func__, rc); - memzero_explicit(kkey, ktp.keylen); - kfree(kkey); - if (rc) - break; - if (copy_to_user(utp, &ktp, sizeof(ktp))) - return -EFAULT; + kfree_sensitive(kkey); + if (!rc && copy_to_user(utp, &ktp, sizeof(ktp))) + rc = -EFAULT; + memzero_explicit(&ktp, sizeof(ktp)); break; } case PKEY_GENSECK2: { @@ -1534,23 +1524,23 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, pr_debug("%s pkey_genseckey2()=%d\n", __func__, rc); kfree(apqns); if (rc) { - kfree(kkey); + kfree_sensitive(kkey); break; } if (kgs.key) { if (kgs.keylen < klen) { - kfree(kkey); + kfree_sensitive(kkey); return -EINVAL; } if (copy_to_user(kgs.key, kkey, klen)) { - kfree(kkey); + kfree_sensitive(kkey); return -EFAULT; } } kgs.keylen = klen; if (copy_to_user(ugs, &kgs, sizeof(kgs))) rc = -EFAULT; - kfree(kkey); + kfree_sensitive(kkey); break; } case PKEY_CLR2SECK2: { @@ -1563,11 +1553,14 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, if (copy_from_user(&kcs, ucs, sizeof(kcs))) return -EFAULT; apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries); - if (IS_ERR(apqns)) + if (IS_ERR(apqns)) { + memzero_explicit(&kcs, sizeof(kcs)); return PTR_ERR(apqns); + } kkey = kzalloc(klen, GFP_KERNEL); if (!kkey) { kfree(apqns); + memzero_explicit(&kcs, sizeof(kcs)); return -ENOMEM; } rc = pkey_clr2seckey2(apqns, kcs.apqn_entries, @@ -1576,16 +1569,19 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, pr_debug("%s pkey_clr2seckey2()=%d\n", __func__, rc); kfree(apqns); if (rc) { - kfree(kkey); + kfree_sensitive(kkey); + memzero_explicit(&kcs, sizeof(kcs)); break; } if (kcs.key) { if (kcs.keylen < klen) { - kfree(kkey); + kfree_sensitive(kkey); + memzero_explicit(&kcs, sizeof(kcs)); return -EINVAL; } if (copy_to_user(kcs.key, kkey, klen)) { - kfree(kkey); + kfree_sensitive(kkey); + memzero_explicit(&kcs, sizeof(kcs)); return -EFAULT; } } @@ -1593,7 +1589,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, if (copy_to_user(ucs, &kcs, sizeof(kcs))) rc = -EFAULT; memzero_explicit(&kcs, sizeof(kcs)); - kfree(kkey); + kfree_sensitive(kkey); break; } case PKEY_VERIFYKEY2: { @@ -1610,7 +1606,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, &kvk.cardnr, &kvk.domain, &kvk.type, &kvk.size, &kvk.flags); pr_debug("%s pkey_verifykey2()=%d\n", __func__, rc); - kfree(kkey); + kfree_sensitive(kkey); if (rc) break; if (copy_to_user(uvk, &kvk, sizeof(kvk))) @@ -1640,12 +1636,10 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, &ktp.protkey.type); pr_debug("%s pkey_keyblob2pkey2()=%d\n", __func__, rc); kfree(apqns); - memzero_explicit(kkey, ktp.keylen); - kfree(kkey); - if (rc) - break; - if (copy_to_user(utp, &ktp, sizeof(ktp))) - return -EFAULT; + kfree_sensitive(kkey); + if (!rc && copy_to_user(utp, &ktp, sizeof(ktp))) + rc = -EFAULT; + memzero_explicit(&ktp, sizeof(ktp)); break; } case PKEY_APQNS4K: { @@ -1673,7 +1667,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, rc = pkey_apqns4key(kkey, kak.keylen, kak.flags, apqns, &nr_apqns); pr_debug("%s pkey_apqns4key()=%d\n", __func__, rc); - kfree(kkey); + kfree_sensitive(kkey); if (rc && rc != -ENOSPC) { kfree(apqns); break; @@ -1759,7 +1753,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, protkey = kmalloc(protkeylen, GFP_KERNEL); if (!protkey) { kfree(apqns); - kfree(kkey); + kfree_sensitive(kkey); return -ENOMEM; } rc = pkey_keyblob2pkey3(apqns, ktp.apqn_entries, @@ -1767,23 +1761,22 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, protkey, &protkeylen, &ktp.pkeytype); pr_debug("%s pkey_keyblob2pkey3()=%d\n", __func__, rc); kfree(apqns); - memzero_explicit(kkey, ktp.keylen); - kfree(kkey); + kfree_sensitive(kkey); if (rc) { - kfree(protkey); + kfree_sensitive(protkey); break; } if (ktp.pkey && ktp.pkeylen) { if (protkeylen > ktp.pkeylen) { - kfree(protkey); + kfree_sensitive(protkey); return -EINVAL; } if (copy_to_user(ktp.pkey, protkey, protkeylen)) { - kfree(protkey); + kfree_sensitive(protkey); return -EFAULT; } } - kfree(protkey); + kfree_sensitive(protkey); ktp.pkeylen = protkeylen; if (copy_to_user(utp, &ktp, sizeof(ktp))) return -EFAULT; |