summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:17:26 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:17:26 +0200
commitb62ed4c93ad71374b54d2c3a72cbc67b506f580c (patch)
tree6ca6ab974bbce902fc9de300fea6aa056170850f /crypto
parent5895db67c12464003afd16c08049b73aa09e58ea (diff)
parent221fc2f4d0eda59d02af2e751a9282fa013a8e97 (diff)
Merge v6.18.40linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/algif_skcipher.c75
-rw-r--r--crypto/asymmetric_keys/verify_pefile.c2
-rw-r--r--crypto/ecrdsa.c2
-rw-r--r--crypto/rng.c11
4 files changed, 38 insertions, 52 deletions
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index ba0a17fd95ac..35ebc3e0201b 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -79,20 +79,6 @@ static int algif_skcipher_export(struct sock *sk, struct skcipher_request *req)
return err;
}
-static void algif_skcipher_done(void *data, int err)
-{
- struct af_alg_async_req *areq = data;
- struct sock *sk = areq->sk;
-
- if (err)
- goto out;
-
- err = algif_skcipher_export(sk, &areq->cra_u.skcipher_req);
-
-out:
- af_alg_async_cb(data, err);
-}
-
static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
size_t ignored, int flags)
{
@@ -171,43 +157,30 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
cflags |= CRYPTO_SKCIPHER_REQ_CONT;
}
- if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) {
- /* AIO operation */
- sock_hold(sk);
- areq->iocb = msg->msg_iocb;
-
- /* Remember output size that will be generated. */
- areq->outlen = len;
-
- skcipher_request_set_callback(&areq->cra_u.skcipher_req,
- cflags |
- CRYPTO_TFM_REQ_MAY_SLEEP,
- algif_skcipher_done, areq);
- err = ctx->enc ?
- crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
- crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
-
- /* AIO operation in progress */
- if (err == -EINPROGRESS)
- return -EIOCBQUEUED;
-
- sock_put(sk);
- } else {
- /* Synchronous operation */
- skcipher_request_set_callback(&areq->cra_u.skcipher_req,
- cflags |
- CRYPTO_TFM_REQ_MAY_SLEEP |
- CRYPTO_TFM_REQ_MAY_BACKLOG,
- crypto_req_done, &ctx->wait);
- err = crypto_wait_req(ctx->enc ?
- crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
- crypto_skcipher_decrypt(&areq->cra_u.skcipher_req),
- &ctx->wait);
-
- if (!err)
- err = algif_skcipher_export(
- sk, &areq->cra_u.skcipher_req);
- }
+ /*
+ * Force synchronous processing. The async (AIO) path passed the
+ * socket-wide ctx->iv into the request, which the worker
+ * dereferenced after the socket lock had been dropped, letting a
+ * concurrent sendmsg(ALG_SET_IV) inject an attacker IV. Mainline
+ * removed the AIO socket path in commit fcc77d33a34c ("net: Remove
+ * support for AIO on sockets"); the minimal stable fix is to always
+ * complete synchronously, so ctx->iv is only ever dereferenced under
+ * the socket lock. This also keeps the IV chaining intact: for
+ * ciphers with statesize == 0 (e.g. ctr, cbc) the chained IV is
+ * carried by the req->iv writeback into ctx->iv, which is only
+ * consistent on the synchronous path.
+ */
+ skcipher_request_set_callback(&areq->cra_u.skcipher_req,
+ cflags |
+ CRYPTO_TFM_REQ_MAY_SLEEP |
+ CRYPTO_TFM_REQ_MAY_BACKLOG,
+ crypto_req_done, &ctx->wait);
+ err = crypto_wait_req(ctx->enc ?
+ crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
+ crypto_skcipher_decrypt(&areq->cra_u.skcipher_req),
+ &ctx->wait);
+ if (!err)
+ err = algif_skcipher_export(sk, &areq->cra_u.skcipher_req);
free:
af_alg_free_resources(areq);
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c
index 1f3b227ba7f2..cec99db14129 100644
--- a/crypto/asymmetric_keys/verify_pefile.c
+++ b/crypto/asymmetric_keys/verify_pefile.c
@@ -305,6 +305,8 @@ static int pefile_digest_pe_contents(const void *pebuf, unsigned int pelen,
if (pelen > hashed_bytes) {
tmp = hashed_bytes + ctx->certs_size;
+ if (tmp <= hashed_bytes || pelen < tmp)
+ return -ELIBBAD;
ret = crypto_shash_update(desc,
pebuf + hashed_bytes,
pelen - tmp);
diff --git a/crypto/ecrdsa.c b/crypto/ecrdsa.c
index 2c0602f0cd40..0cd7eb367604 100644
--- a/crypto/ecrdsa.c
+++ b/crypto/ecrdsa.c
@@ -145,7 +145,7 @@ int ecrdsa_param_curve(void *context, size_t hdrlen, unsigned char tag,
struct ecrdsa_ctx *ctx = context;
ctx->curve_oid = look_up_OID(value, vlen);
- if (!ctx->curve_oid)
+ if (ctx->curve_oid == OID__NR)
return -EINVAL;
ctx->curve = get_curve_by_oid(ctx->curve_oid);
return 0;
diff --git a/crypto/rng.c b/crypto/rng.c
index ee1768c5a400..b021936094b0 100644
--- a/crypto/rng.c
+++ b/crypto/rng.c
@@ -226,5 +226,16 @@ void crypto_unregister_rngs(struct rng_alg *algs, int count)
}
EXPORT_SYMBOL_GPL(crypto_unregister_rngs);
+static void __exit rng_exit(void)
+{
+ int err;
+
+ err = crypto_del_default_rng();
+ if (err)
+ pr_err("Failed delete default RNG: %d\n", err);
+}
+
+module_exit(rng_exit);
+
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Random Number Generator");