diff --git a/crypto/af_alg.c b/crypto/af_alg.c index ea6fb8e89d06..68cc9290cabe 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -1116,9 +1116,13 @@ EXPORT_SYMBOL_GPL(af_alg_sendmsg); void af_alg_free_resources(struct af_alg_async_req *areq) { struct sock *sk = areq->sk; + struct af_alg_ctx *ctx; af_alg_free_areq_sgls(areq); sock_kfree_s(sk, areq, areq->areqlen); + + ctx = alg_sk(sk)->private; + ctx->inflight = false; } EXPORT_SYMBOL_GPL(af_alg_free_resources); @@ -1188,11 +1192,19 @@ EXPORT_SYMBOL_GPL(af_alg_poll); struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, unsigned int areqlen) { - struct af_alg_async_req *areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); + struct af_alg_ctx *ctx = alg_sk(sk)->private; + struct af_alg_async_req *areq; + /* Only one AIO request can be in flight. */ + if (ctx->inflight) + return ERR_PTR(-EBUSY); + + areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); if (unlikely(!areq)) return ERR_PTR(-ENOMEM); + ctx->inflight = true; + areq->areqlen = areqlen; areq->sk = sk; areq->first_rsgl.sgl.sgt.sgl = areq->first_rsgl.sgl.sgl; diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index ef8ce86b1f78..08b803a4fcde 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -136,6 +136,7 @@ struct af_alg_async_req { * recvmsg is invoked. * @init: True if metadata has been sent. * @len: Length of memory allocated for this data structure. + * @inflight: Non-zero when AIO requests are in flight. */ struct af_alg_ctx { struct list_head tsgl_list; @@ -154,6 +155,8 @@ struct af_alg_ctx { bool init; unsigned int len; + + unsigned int inflight; }; int af_alg_register_type(const struct af_alg_type *type);