s390/pkey: Wipe copies of clear-key structures on failure
[linux-2.6-block.git] / drivers / s390 / crypto / pkey_api.c
index 179287157c2fe1e8a2f03eb10ba8e09077f29c5c..1aa78a74fbaded85fa6e0387d6b4e52cf3487d28 100644 (file)
@@ -1374,9 +1374,7 @@ 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)))
+               if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs)))
                        rc = -EFAULT;
                memzero_explicit(&kcs, sizeof(kcs));
                break;
@@ -1409,9 +1407,7 @@ 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)))
+               if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp)))
                        rc = -EFAULT;
                memzero_explicit(&kcp, sizeof(kcp));
                break;
@@ -1562,11 +1558,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,15 +1575,18 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
                kfree(apqns);
                if (rc) {
                        kfree(kkey);
+                       memzero_explicit(&kcs, sizeof(kcs));
                        break;
                }
                if (kcs.key) {
                        if (kcs.keylen < klen) {
                                kfree(kkey);
+                               memzero_explicit(&kcs, sizeof(kcs));
                                return -EINVAL;
                        }
                        if (copy_to_user(kcs.key, kkey, klen)) {
                                kfree(kkey);
+                               memzero_explicit(&kcs, sizeof(kcs));
                                return -EFAULT;
                        }
                }