FAILED: patch "[PATCH] s390/crypto: Fix return code handling at skcipher_walk_done" failed to apply to 6.18-stable tree
[email protected]
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 403648373816ae8eb76fe4a393836b0d65fa8f85
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091641-pushup-although-90f6@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 403648373816ae8eb76fe4a393836b0d65fa8f85 Mon Sep 17 00:00:00 2001
From: Harald Freudenberger <[email protected]>
Date: Mon, 31 Aug 2026 10:38:30 +0200
Subject: [PATCH] s390/crypto: Fix return code handling at skcipher_walk_done
in PAES algorithms
All the 4 PAES cipher processing loops were not checking the return value of skcipher_walk_done() immediately after calling it. This could lead to error masking when both the walk operation failed and a subsequent key conversion was needed (k < n condition).
Add immediate error checks after skcipher_walk_done() in all main processing loops (ECB, CBC, CTR, XTS modes) to ensure walk errors are properly propagated and not masked by subsequent operations.
With that comes a slight rework around the skcipher_walk_done() invocation. It is now necessary to check if the walk has already been finalized (walk->nbytes is then 0) or not to avoid double de-allocation of resources held by the walk.
arch/s390/crypto/paes_s390.c +27 -11
@@ -432,8 +432,11 @@ static int ecb_paes_do_crypt(struct s390_paes_ctx *ctx, n = nbytes & ~(AES_BLOCK_SIZE -1 ); k =cpacf_km (ctx->fc | req_ctx->modifier, param, walk->dst.virt.addr, walk->src.virt.addr, n); -if (k) +if (k) { rc =skcipher_walk_done (walk, nbytes - k); +if (rc) + goto out; + }if (k < n) {if (!maysleep) { rc = -EKEYEXPIRED ;
@@ -495,7 +498,7 @@ static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)atomic_dec (&ctx->via_engine_ctr); } -if (rc != -EINPROGRESS ) +if (rc != -EINPROGRESS && walk->nbytes)skcipher_walk_done (walk, rc); out:
@@ -549,7 +552,7 @@ static int ecb_paes_do_one_request(struct crypto_engine *engine, void *areq) rc =ecb_paes_do_crypt (ctx, req_ctx, tested, true);if (rc == -EKEYEXPIRED ) {return pkey_handle_expired (); - }else if (rc) { + }else if (rc && walk->nbytes) {skcipher_walk_done (walk, rc); }
@@ -690,6 +693,8 @@ static int cbc_paes_do_crypt(struct s390_paes_ctx *ctx,if (k) {memcpy (walk->iv, param->iv,AES_BLOCK_SIZE ); rc =skcipher_walk_done (walk, nbytes - k); +if (rc) + goto out; }if (k < n) {if (!maysleep) {
@@ -752,7 +757,7 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)atomic_dec (&ctx->via_engine_ctr); } -if (rc != -EINPROGRESS ) +if (rc != -EINPROGRESS && walk->nbytes)skcipher_walk_done (walk, rc); out:
@@ -806,7 +811,7 @@ static int cbc_paes_do_one_request(struct crypto_engine *engine, void *areq) rc =cbc_paes_do_crypt (ctx, req_ctx, tested, true);if (rc == -EKEYEXPIRED ) {return pkey_handle_expired (); - }else if (rc) { + }else if (rc && walk->nbytes) {skcipher_walk_done (walk, rc); }
@@ -968,6 +973,11 @@ static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx, AES_BLOCK_SIZE);crypto_inc (walk->iv,AES_BLOCK_SIZE ); rc =skcipher_walk_done (walk, nbytes - k); +if (rc) { +if (locked) +mutex_unlock (&ctrblk_lock); + goto out; + } }if (k < n) {if (!maysleep) {
@@ -1061,7 +1071,7 @@ static int ctr_paes_crypt(struct skcipher_request *req)atomic_dec (&ctx->via_engine_ctr); } -if (rc != -EINPROGRESS ) +if (rc != -EINPROGRESS && walk->nbytes)skcipher_walk_done (walk, rc); out:
@@ -1105,7 +1115,7 @@ static int ctr_paes_do_one_request(struct crypto_engine *engine, void *areq) rc =ctr_paes_do_crypt (ctx, req_ctx, tested, true);if (rc == -EKEYEXPIRED ) {return pkey_handle_expired (); - }else if (rc) { + }else if (rc && walk->nbytes) {skcipher_walk_done (walk, rc); }
@@ -1283,8 +1293,11 @@ static int xts_paes_do_crypt_fullkey(struct s390_pxts_ctx *ctx, n = nbytes & ~(AES_BLOCK_SIZE -1 ); k =cpacf_km (ctx->fc | req_ctx->modifier, param->key + offset, walk->dst.virt.addr, walk->src.virt.addr, n); -if (k) +if (k) { rc =skcipher_walk_done (walk, nbytes - k); +if (rc) + goto out; + }if (k < n) {if (!maysleep) { rc = -EKEYEXPIRED ;
@@ -1377,8 +1390,11 @@ static int xts_paes_do_crypt_2keys(struct s390_pxts_ctx *ctx, n = nbytes & ~(AES_BLOCK_SIZE -1 ); k =cpacf_km (ctx->fc | req_ctx->modifier, param->key + offset, walk->dst.virt.addr, walk->src.virt.addr, n); -if (k) +if (k) { rc =skcipher_walk_done (walk, nbytes - k); +if (rc) + goto out; + }if (k < n) {if (!maysleep) { rc = -EKEYEXPIRED ;
@@ -1485,7 +1501,7 @@ static inline int xts_paes_crypt(struct skcipher_request *req, unsigned long modatomic_dec (&ctx->via_engine_ctr); } -if (rc != -EINPROGRESS ) +if (rc != -EINPROGRESS && walk->nbytes)skcipher_walk_done (walk, rc); out:
@@ -1539,7 +1555,7 @@ static int xts_paes_do_one_request(struct crypto_engine *engine, void *areq) rc =xts_paes_do_crypt (ctx, req_ctx, tested, true);if (rc == -EKEYEXPIRED ) {return pkey_handle_expired (); - }else if (rc) { + }else if (rc && walk->nbytes) {skcipher_walk_done (walk, rc); }