Skip to content

Commit 3ad81aa

Browse files
committed
Merge tag 'v6.18-p4' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu: - Fix double free in aspeed - Fix req->nbytes clobbering in s390/phmac * tag 'v6.18-p4' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: crypto: aspeed - fix double free caused by devm crypto: s390/phmac - Do not modify the req->nbytes value
2 parents 2d51cb1 + 3c9bf72 commit 3ad81aa

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

arch/s390/crypto/phmac_s390.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,18 @@ struct kmac_sha2_ctx {
169169
u64 buflen[2];
170170
};
171171

172+
enum async_op {
173+
OP_NOP = 0,
174+
OP_UPDATE,
175+
OP_FINAL,
176+
OP_FINUP,
177+
};
178+
172179
/* phmac request context */
173180
struct phmac_req_ctx {
174181
struct hash_walk_helper hwh;
175182
struct kmac_sha2_ctx kmac_ctx;
176-
bool final;
183+
enum async_op async_op;
177184
};
178185

179186
/*
@@ -610,6 +617,7 @@ static int phmac_update(struct ahash_request *req)
610617
* using engine to serialize requests.
611618
*/
612619
if (rc == 0 || rc == -EKEYEXPIRED) {
620+
req_ctx->async_op = OP_UPDATE;
613621
atomic_inc(&tfm_ctx->via_engine_ctr);
614622
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
615623
if (rc != -EINPROGRESS)
@@ -647,8 +655,7 @@ static int phmac_final(struct ahash_request *req)
647655
* using engine to serialize requests.
648656
*/
649657
if (rc == 0 || rc == -EKEYEXPIRED) {
650-
req->nbytes = 0;
651-
req_ctx->final = true;
658+
req_ctx->async_op = OP_FINAL;
652659
atomic_inc(&tfm_ctx->via_engine_ctr);
653660
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
654661
if (rc != -EINPROGRESS)
@@ -676,13 +683,16 @@ static int phmac_finup(struct ahash_request *req)
676683
if (rc)
677684
goto out;
678685

686+
req_ctx->async_op = OP_FINUP;
687+
679688
/* Try synchronous operations if no active engine usage */
680689
if (!atomic_read(&tfm_ctx->via_engine_ctr)) {
681690
rc = phmac_kmac_update(req, false);
682691
if (rc == 0)
683-
req->nbytes = 0;
692+
req_ctx->async_op = OP_FINAL;
684693
}
685-
if (!rc && !req->nbytes && !atomic_read(&tfm_ctx->via_engine_ctr)) {
694+
if (!rc && req_ctx->async_op == OP_FINAL &&
695+
!atomic_read(&tfm_ctx->via_engine_ctr)) {
686696
rc = phmac_kmac_final(req, false);
687697
if (rc == 0)
688698
goto out;
@@ -694,7 +704,7 @@ static int phmac_finup(struct ahash_request *req)
694704
* using engine to serialize requests.
695705
*/
696706
if (rc == 0 || rc == -EKEYEXPIRED) {
697-
req_ctx->final = true;
707+
/* req->async_op has been set to either OP_FINUP or OP_FINAL */
698708
atomic_inc(&tfm_ctx->via_engine_ctr);
699709
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
700710
if (rc != -EINPROGRESS)
@@ -855,15 +865,16 @@ static int phmac_do_one_request(struct crypto_engine *engine, void *areq)
855865

856866
/*
857867
* Three kinds of requests come in here:
858-
* update when req->nbytes > 0 and req_ctx->final is false
859-
* final when req->nbytes = 0 and req_ctx->final is true
860-
* finup when req->nbytes > 0 and req_ctx->final is true
861-
* For update and finup the hwh walk needs to be prepared and
862-
* up to date but the actual nr of bytes in req->nbytes may be
863-
* any non zero number. For final there is no hwh walk needed.
868+
* 1. req->async_op == OP_UPDATE with req->nbytes > 0
869+
* 2. req->async_op == OP_FINUP with req->nbytes > 0
870+
* 3. req->async_op == OP_FINAL
871+
* For update and finup the hwh walk has already been prepared
872+
* by the caller. For final there is no hwh walk needed.
864873
*/
865874

866-
if (req->nbytes) {
875+
switch (req_ctx->async_op) {
876+
case OP_UPDATE:
877+
case OP_FINUP:
867878
rc = phmac_kmac_update(req, true);
868879
if (rc == -EKEYEXPIRED) {
869880
/*
@@ -880,10 +891,11 @@ static int phmac_do_one_request(struct crypto_engine *engine, void *areq)
880891
hwh_advance(hwh, rc);
881892
goto out;
882893
}
883-
req->nbytes = 0;
884-
}
885-
886-
if (req_ctx->final) {
894+
if (req_ctx->async_op == OP_UPDATE)
895+
break;
896+
req_ctx->async_op = OP_FINAL;
897+
fallthrough;
898+
case OP_FINAL:
887899
rc = phmac_kmac_final(req, true);
888900
if (rc == -EKEYEXPIRED) {
889901
/*
@@ -897,10 +909,14 @@ static int phmac_do_one_request(struct crypto_engine *engine, void *areq)
897909
cond_resched();
898910
return -ENOSPC;
899911
}
912+
break;
913+
default:
914+
/* unknown/unsupported/unimplemented asynch op */
915+
return -EOPNOTSUPP;
900916
}
901917

902918
out:
903-
if (rc || req_ctx->final)
919+
if (rc || req_ctx->async_op == OP_FINAL)
904920
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
905921
pr_debug("request complete with rc=%d\n", rc);
906922
local_bh_disable();

drivers/crypto/aspeed/aspeed-acry.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,6 @@ static int aspeed_acry_probe(struct platform_device *pdev)
787787
err_engine_rsa_start:
788788
crypto_engine_exit(acry_dev->crypt_engine_rsa);
789789
clk_exit:
790-
clk_disable_unprepare(acry_dev->clk);
791790

792791
return rc;
793792
}
@@ -799,7 +798,6 @@ static void aspeed_acry_remove(struct platform_device *pdev)
799798
aspeed_acry_unregister(acry_dev);
800799
crypto_engine_exit(acry_dev->crypt_engine_rsa);
801800
tasklet_kill(&acry_dev->done_task);
802-
clk_disable_unprepare(acry_dev->clk);
803801
}
804802

805803
MODULE_DEVICE_TABLE(of, aspeed_acry_of_matches);

0 commit comments

Comments
 (0)