Skip to content

Commit

Permalink
crypto: algif_aead - Only wake up when ctx->more is zero
Browse files Browse the repository at this point in the history
AEAD does not support partial requests so we must not wake up
while ctx->more is set.  In order to distinguish between the
case of no data sent yet and a zero-length request, a new init
flag has been added to ctx.

SKCIPHER has also been modified to ensure that at least a block
of data is available if there is more data to come.

Fixes: 2d97591 ("crypto: af_alg - consolidation of...")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
herbertx committed Jun 18, 2020
1 parent 1532e31 commit f3c802a
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 8 deletions.
11 changes: 8 additions & 3 deletions crypto/af_alg.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,

if (!ctx->used)
ctx->merge = 0;
ctx->init = ctx->more;
}
EXPORT_SYMBOL_GPL(af_alg_pull_tsgl);

Expand Down Expand Up @@ -734,9 +735,10 @@ EXPORT_SYMBOL_GPL(af_alg_wmem_wakeup);
*
* @sk socket of connection to user space
* @flags If MSG_DONTWAIT is set, then only report if function would sleep
* @min Set to minimum request size if partial requests are allowed.
* @return 0 when writable memory is available, < 0 upon error
*/
int af_alg_wait_for_data(struct sock *sk, unsigned flags)
int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min)
{
DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct alg_sock *ask = alg_sk(sk);
Expand All @@ -754,7 +756,9 @@ int af_alg_wait_for_data(struct sock *sk, unsigned flags)
if (signal_pending(current))
break;
timeout = MAX_SCHEDULE_TIMEOUT;
if (sk_wait_event(sk, &timeout, (ctx->used || !ctx->more),
if (sk_wait_event(sk, &timeout,
ctx->init && (!ctx->more ||
(min && ctx->used >= min)),
&wait)) {
err = 0;
break;
Expand Down Expand Up @@ -843,7 +847,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
}

lock_sock(sk);
if (!ctx->more && ctx->used) {
if (ctx->init && (init || !ctx->more)) {
err = -EINVAL;
goto unlock;
}
Expand All @@ -854,6 +858,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
memcpy(ctx->iv, con.iv->iv, ivsize);

ctx->aead_assoclen = con.aead_assoclen;
ctx->init = true;
}

while (size) {
Expand Down
4 changes: 2 additions & 2 deletions crypto/algif_aead.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
size_t usedpages = 0; /* [in] RX bufs to be used from user */
size_t processed = 0; /* [in] TX bufs to be consumed */

if (!ctx->used) {
err = af_alg_wait_for_data(sk, flags);
if (!ctx->init || ctx->more) {
err = af_alg_wait_for_data(sk, flags, 0);
if (err)
return err;
}
Expand Down
4 changes: 2 additions & 2 deletions crypto/algif_skcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
int err = 0;
size_t len = 0;

if (!ctx->used) {
err = af_alg_wait_for_data(sk, flags);
if (!ctx->init || (ctx->more && ctx->used < bs)) {
err = af_alg_wait_for_data(sk, flags, bs);
if (err)
return err;
}
Expand Down
4 changes: 3 additions & 1 deletion include/crypto/if_alg.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ struct af_alg_async_req {
* SG?
* @enc: Cryptographic operation to be performed when
* recvmsg is invoked.
* @init: True if metadata has been sent.
* @len: Length of memory allocated for this data structure.
*/
struct af_alg_ctx {
Expand All @@ -151,6 +152,7 @@ struct af_alg_ctx {
bool more;
bool merge;
bool enc;
bool init;

unsigned int len;
};
Expand Down Expand Up @@ -226,7 +228,7 @@ unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset);
void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
size_t dst_offset);
void af_alg_wmem_wakeup(struct sock *sk);
int af_alg_wait_for_data(struct sock *sk, unsigned flags);
int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min);
int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
unsigned int ivsize);
ssize_t af_alg_sendpage(struct socket *sock, struct page *page,
Expand Down

0 comments on commit f3c802a

Please sign in to comment.