diff options
| author | Herbert Xu <herbert@gondor.apana.org.au> | 2010-11-30 04:04:31 -0500 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-11-30 04:04:31 -0500 |
| commit | bc97e57eb21f8db55bf0e1f182d384e75b2e3c99 (patch) | |
| tree | 470a1564aaa3d36f545bb7b4d25e853a38617f01 /crypto | |
| parent | 0f6bb83cb12e4617e696ffa566f3fc6c092686e2 (diff) | |
crypto: algif_skcipher - Handle unaligned receive buffer
As it is if user-space passes through a receive buffer that's not
aligned to to the cipher block size, we'll end up encrypting or
decrypting a partial block which causes a spurious EINVAL to be
returned.
This patch fixes this by moving the partial block test after the
af_alg_make_sg call.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/algif_skcipher.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 1f33480e3260..6a6dfc062d2a 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c | |||
| @@ -454,17 +454,17 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, | |||
| 454 | 454 | ||
| 455 | used = min_t(unsigned long, used, seglen); | 455 | used = min_t(unsigned long, used, seglen); |
| 456 | 456 | ||
| 457 | used = af_alg_make_sg(&ctx->rsgl, from, used, 1); | ||
| 458 | err = used; | ||
| 459 | if (err < 0) | ||
| 460 | goto unlock; | ||
| 461 | |||
| 457 | if (ctx->more || used < ctx->used) | 462 | if (ctx->more || used < ctx->used) |
| 458 | used -= used % bs; | 463 | used -= used % bs; |
| 459 | 464 | ||
| 460 | err = -EINVAL; | 465 | err = -EINVAL; |
| 461 | if (!used) | 466 | if (!used) |
| 462 | goto unlock; | 467 | goto free; |
| 463 | |||
| 464 | used = af_alg_make_sg(&ctx->rsgl, from, used, 1); | ||
| 465 | err = used; | ||
| 466 | if (err < 0) | ||
| 467 | goto unlock; | ||
| 468 | 468 | ||
| 469 | ablkcipher_request_set_crypt(&ctx->req, sg, | 469 | ablkcipher_request_set_crypt(&ctx->req, sg, |
| 470 | ctx->rsgl.sg, used, | 470 | ctx->rsgl.sg, used, |
| @@ -476,6 +476,7 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, | |||
| 476 | crypto_ablkcipher_decrypt(&ctx->req), | 476 | crypto_ablkcipher_decrypt(&ctx->req), |
| 477 | &ctx->completion); | 477 | &ctx->completion); |
| 478 | 478 | ||
| 479 | free: | ||
| 479 | af_alg_free_sg(&ctx->rsgl); | 480 | af_alg_free_sg(&ctx->rsgl); |
| 480 | 481 | ||
| 481 | if (err) | 482 | if (err) |
