Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/pkey: Wipe copies of protected- and secure-keys

Although the clear-key of neither protected- nor secure-keys is
accessible, this key material should only be visible to the calling
process. So wipe all copies of protected- or secure-keys from stack,
even in case of an error.

Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>

authored by

Holger Dengler and committed by
Alexander Gordeev
f2ebdadd d65d76a4

+37 -43
+37 -43
drivers/s390/crypto/pkey_api.c
··· 1359 1359 rc = cca_genseckey(kgs.cardnr, kgs.domain, 1360 1360 kgs.keytype, kgs.seckey.seckey); 1361 1361 pr_debug("%s cca_genseckey()=%d\n", __func__, rc); 1362 - if (rc) 1363 - break; 1364 - if (copy_to_user(ugs, &kgs, sizeof(kgs))) 1365 - return -EFAULT; 1362 + if (!rc && copy_to_user(ugs, &kgs, sizeof(kgs))) 1363 + rc = -EFAULT; 1364 + memzero_explicit(&kgs, sizeof(kgs)); 1366 1365 break; 1367 1366 } 1368 1367 case PKEY_CLR2SECK: { ··· 1389 1390 ksp.seckey.seckey, ksp.protkey.protkey, 1390 1391 &ksp.protkey.len, &ksp.protkey.type); 1391 1392 pr_debug("%s cca_sec2protkey()=%d\n", __func__, rc); 1392 - if (rc) 1393 - break; 1394 - if (copy_to_user(usp, &ksp, sizeof(ksp))) 1395 - return -EFAULT; 1393 + if (!rc && copy_to_user(usp, &ksp, sizeof(ksp))) 1394 + rc = -EFAULT; 1395 + memzero_explicit(&ksp, sizeof(ksp)); 1396 1396 break; 1397 1397 } 1398 1398 case PKEY_CLR2PROTK: { ··· 1435 1437 rc = pkey_skey2pkey(ksp.seckey.seckey, ksp.protkey.protkey, 1436 1438 &ksp.protkey.len, &ksp.protkey.type); 1437 1439 pr_debug("%s pkey_skey2pkey()=%d\n", __func__, rc); 1438 - if (rc) 1439 - break; 1440 - if (copy_to_user(usp, &ksp, sizeof(ksp))) 1441 - return -EFAULT; 1440 + if (!rc && copy_to_user(usp, &ksp, sizeof(ksp))) 1441 + rc = -EFAULT; 1442 + memzero_explicit(&ksp, sizeof(ksp)); 1442 1443 break; 1443 1444 } 1444 1445 case PKEY_VERIFYKEY: { ··· 1449 1452 rc = pkey_verifykey(&kvk.seckey, &kvk.cardnr, &kvk.domain, 1450 1453 &kvk.keysize, &kvk.attributes); 1451 1454 pr_debug("%s pkey_verifykey()=%d\n", __func__, rc); 1452 - if (rc) 1453 - break; 1454 - if (copy_to_user(uvk, &kvk, sizeof(kvk))) 1455 - return -EFAULT; 1455 + if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk))) 1456 + rc = -EFAULT; 1457 + memzero_explicit(&kvk, sizeof(kvk)); 1456 1458 break; 1457 1459 } 1458 1460 case PKEY_GENPROTK: { ··· 1464 1468 rc = pkey_genprotkey(kgp.keytype, kgp.protkey.protkey, 1465 1469 &kgp.protkey.len, &kgp.protkey.type); 1466 1470 pr_debug("%s pkey_genprotkey()=%d\n", __func__, rc); 1467 - if (rc) 1468 - break; 1469 - if (copy_to_user(ugp, &kgp, sizeof(kgp))) 1470 - return -EFAULT; 1471 + if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp))) 1472 + rc = -EFAULT; 1473 + memzero_explicit(&kgp, sizeof(kgp)); 1471 1474 break; 1472 1475 } 1473 1476 case PKEY_VERIFYPROTK: { ··· 1478 1483 rc = pkey_verifyprotkey(kvp.protkey.protkey, 1479 1484 kvp.protkey.len, kvp.protkey.type); 1480 1485 pr_debug("%s pkey_verifyprotkey()=%d\n", __func__, rc); 1486 + memzero_explicit(&kvp, sizeof(kvp)); 1481 1487 break; 1482 1488 } 1483 1489 case PKEY_KBLOB2PROTK: { ··· 1496 1500 &ktp.protkey.len, &ktp.protkey.type); 1497 1501 pr_debug("%s pkey_keyblob2pkey()=%d\n", __func__, rc); 1498 1502 kfree_sensitive(kkey); 1499 - if (rc) 1500 - break; 1501 - if (copy_to_user(utp, &ktp, sizeof(ktp))) 1502 - return -EFAULT; 1503 + if (!rc && copy_to_user(utp, &ktp, sizeof(ktp))) 1504 + rc = -EFAULT; 1505 + memzero_explicit(&ktp, sizeof(ktp)); 1503 1506 break; 1504 1507 } 1505 1508 case PKEY_GENSECK2: { ··· 1524 1529 pr_debug("%s pkey_genseckey2()=%d\n", __func__, rc); 1525 1530 kfree(apqns); 1526 1531 if (rc) { 1527 - kfree(kkey); 1532 + kfree_sensitive(kkey); 1528 1533 break; 1529 1534 } 1530 1535 if (kgs.key) { 1531 1536 if (kgs.keylen < klen) { 1532 - kfree(kkey); 1537 + kfree_sensitive(kkey); 1533 1538 return -EINVAL; 1534 1539 } 1535 1540 if (copy_to_user(kgs.key, kkey, klen)) { 1536 - kfree(kkey); 1541 + kfree_sensitive(kkey); 1537 1542 return -EFAULT; 1538 1543 } 1539 1544 } 1540 1545 kgs.keylen = klen; 1541 1546 if (copy_to_user(ugs, &kgs, sizeof(kgs))) 1542 1547 rc = -EFAULT; 1543 - kfree(kkey); 1548 + kfree_sensitive(kkey); 1544 1549 break; 1545 1550 } 1546 1551 case PKEY_CLR2SECK2: { ··· 1569 1574 pr_debug("%s pkey_clr2seckey2()=%d\n", __func__, rc); 1570 1575 kfree(apqns); 1571 1576 if (rc) { 1572 - kfree(kkey); 1577 + kfree_sensitive(kkey); 1573 1578 memzero_explicit(&kcs, sizeof(kcs)); 1574 1579 break; 1575 1580 } 1576 1581 if (kcs.key) { 1577 1582 if (kcs.keylen < klen) { 1578 - kfree(kkey); 1583 + kfree_sensitive(kkey); 1579 1584 memzero_explicit(&kcs, sizeof(kcs)); 1580 1585 return -EINVAL; 1581 1586 } 1582 1587 if (copy_to_user(kcs.key, kkey, klen)) { 1583 - kfree(kkey); 1588 + kfree_sensitive(kkey); 1584 1589 memzero_explicit(&kcs, sizeof(kcs)); 1585 1590 return -EFAULT; 1586 1591 } ··· 1589 1594 if (copy_to_user(ucs, &kcs, sizeof(kcs))) 1590 1595 rc = -EFAULT; 1591 1596 memzero_explicit(&kcs, sizeof(kcs)); 1592 - kfree(kkey); 1597 + kfree_sensitive(kkey); 1593 1598 break; 1594 1599 } 1595 1600 case PKEY_VERIFYKEY2: { ··· 1606 1611 &kvk.cardnr, &kvk.domain, 1607 1612 &kvk.type, &kvk.size, &kvk.flags); 1608 1613 pr_debug("%s pkey_verifykey2()=%d\n", __func__, rc); 1609 - kfree(kkey); 1614 + kfree_sensitive(kkey); 1610 1615 if (rc) 1611 1616 break; 1612 1617 if (copy_to_user(uvk, &kvk, sizeof(kvk))) ··· 1637 1642 pr_debug("%s pkey_keyblob2pkey2()=%d\n", __func__, rc); 1638 1643 kfree(apqns); 1639 1644 kfree_sensitive(kkey); 1640 - if (rc) 1641 - break; 1642 - if (copy_to_user(utp, &ktp, sizeof(ktp))) 1643 - return -EFAULT; 1645 + if (!rc && copy_to_user(utp, &ktp, sizeof(ktp))) 1646 + rc = -EFAULT; 1647 + memzero_explicit(&ktp, sizeof(ktp)); 1644 1648 break; 1645 1649 } 1646 1650 case PKEY_APQNS4K: { ··· 1667 1673 rc = pkey_apqns4key(kkey, kak.keylen, kak.flags, 1668 1674 apqns, &nr_apqns); 1669 1675 pr_debug("%s pkey_apqns4key()=%d\n", __func__, rc); 1670 - kfree(kkey); 1676 + kfree_sensitive(kkey); 1671 1677 if (rc && rc != -ENOSPC) { 1672 1678 kfree(apqns); 1673 1679 break; ··· 1753 1759 protkey = kmalloc(protkeylen, GFP_KERNEL); 1754 1760 if (!protkey) { 1755 1761 kfree(apqns); 1756 - kfree(kkey); 1762 + kfree_sensitive(kkey); 1757 1763 return -ENOMEM; 1758 1764 } 1759 1765 rc = pkey_keyblob2pkey3(apqns, ktp.apqn_entries, ··· 1763 1769 kfree(apqns); 1764 1770 kfree_sensitive(kkey); 1765 1771 if (rc) { 1766 - kfree(protkey); 1772 + kfree_sensitive(protkey); 1767 1773 break; 1768 1774 } 1769 1775 if (ktp.pkey && ktp.pkeylen) { 1770 1776 if (protkeylen > ktp.pkeylen) { 1771 - kfree(protkey); 1777 + kfree_sensitive(protkey); 1772 1778 return -EINVAL; 1773 1779 } 1774 1780 if (copy_to_user(ktp.pkey, protkey, protkeylen)) { 1775 - kfree(protkey); 1781 + kfree_sensitive(protkey); 1776 1782 return -EFAULT; 1777 1783 } 1778 1784 } 1779 - kfree(protkey); 1785 + kfree_sensitive(protkey); 1780 1786 ktp.pkeylen = protkeylen; 1781 1787 if (copy_to_user(utp, &ktp, sizeof(ktp))) 1782 1788 return -EFAULT;