From 58ede126ccdd833a1559717c2cdeb35c4410921b Mon Sep 17 00:00:00 2001 From: Ingo Franzki Date: Mon, 29 Jun 2026 08:59:27 +0200 Subject: [PATCH] zkey: Retry PKEY_KBLOB2PROTK3 ioctl in case of EBUSY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After a master key change, it can happen that the PKEY_KBLOB2PROTK3 ioctl returns EBUSY. This is a temporary situation and the operation will succeed, once the firmware has completed some internal processing related with the master key change. Delay 1 second and retry up to 10 times. A similar retry loop was previously used for the AF_ALG-based handling, but the retry logic was not included for the new ioctl-based handling. Fixes: 7fffdcfe8cae ("zkey: Remove the use of AF_ALG for calculating key verification patterns") Signed-off-by: Ingo Franzki Reviewed-by: Finn Callies Signed-off-by: Jan Höppner --- zkey/pkey.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/zkey/pkey.c b/zkey/pkey.c index 2b2e41c4..8d5ebf58 100644 --- a/zkey/pkey.c +++ b/zkey/pkey.c @@ -1476,6 +1476,7 @@ static int pkey_kblob2protk(int pkey_fd, u8 *key, size_t key_size, u32 list_entries = 0, pkeylen = 0, type; struct pkey_kblob2pkey3 kblob2pkey3; struct pkey_apqn *list = NULL; + int retry_count = 0; bool securekey, xts; u32 flags = 0; int rc; @@ -1509,6 +1510,7 @@ static int pkey_kblob2protk(int pkey_fd, u8 *key, size_t key_size, } } +retry1: kblob2pkey3.key = key; kblob2pkey3.keylen = HALF_KEYSIZE_FOR_XTS(key_size, xts); kblob2pkey3.apqns = list; @@ -1522,6 +1524,20 @@ static int pkey_kblob2protk(int pkey_fd, u8 *key, size_t key_size, rc = -errno; pr_verbose(verbose, "ioctl PKEY_KBLOB2PROTK3 rc: %s", strerror(-rc)); + + /* + * After a master key change, it can happen that the + * PKEY_KBLOB2PROTK3 ioctl returns EBUSY. This is a temporary + * situation and the operation will succeed, once the firmware + * has completed some internal processing related with the + * master key change. Delay 1 second and retry up to 10 times. + */ + if (rc == -EBUSY && retry_count < 10) { + pr_verbose(verbose, "Retrying after 1 second..."); + retry_count++; + sleep(1); + goto retry1; + } goto out; } @@ -1535,6 +1551,7 @@ static int pkey_kblob2protk(int pkey_fd, u8 *key, size_t key_size, goto out; } +retry2: kblob2pkey3.key = key + key_size / 2; kblob2pkey3.keylen = key_size / 2; kblob2pkey3.apqns = list; @@ -1548,6 +1565,22 @@ static int pkey_kblob2protk(int pkey_fd, u8 *key, size_t key_size, rc = -errno; pr_verbose(verbose, "ioctl PKEY_KBLOB2PROTK3 rc: %s", strerror(-rc)); + + /* + * After a master key change, it can happen that the + * PKEY_KBLOB2PROTK3 ioctl returns EBUSY. This is a + * temporary situation and the operation will succeed, + * once the firmware has completed some internal + * processing related with the master key change. + * Delay 1 second and retry up to 10 times. + */ + if (rc == -EBUSY && retry_count < 10) { + pr_verbose(verbose, + "Retrying after 1 second..."); + retry_count++; + sleep(1); + goto retry2; + } goto out; }