diff options
| author | Kees Cook <keescook@chromium.org> | 2018-08-07 17:18:42 -0400 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2018-09-03 23:37:03 -0400 |
| commit | f3569fd613f669c95ad187208ad281995f30cc2a (patch) | |
| tree | 7e5516a5ba41982e79f2493a3eba2327d4da4586 /crypto | |
| parent | 1299c9cfae6dccd79e4e035cad44f99fdb828593 (diff) | |
crypto: shash - Remove VLA usage in unaligned hashing
In the quest to remove all stack VLA usage from the kernel[1], this uses
the newly defined max alignment to perform unaligned hashing to avoid
VLAs, and drops the helper function while adding sanity checks on the
resulting buffer sizes. Additionally, the __aligned_largest macro is
removed since this helper was the only user.
[1] https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/shash.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/crypto/shash.c b/crypto/shash.c index 86d76b5c626c..d21f04d70dce 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
| @@ -73,13 +73,6 @@ int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key, | |||
| 73 | } | 73 | } |
| 74 | EXPORT_SYMBOL_GPL(crypto_shash_setkey); | 74 | EXPORT_SYMBOL_GPL(crypto_shash_setkey); |
| 75 | 75 | ||
| 76 | static inline unsigned int shash_align_buffer_size(unsigned len, | ||
| 77 | unsigned long mask) | ||
| 78 | { | ||
| 79 | typedef u8 __aligned_largest u8_aligned; | ||
| 80 | return len + (mask & ~(__alignof__(u8_aligned) - 1)); | ||
| 81 | } | ||
| 82 | |||
| 83 | static int shash_update_unaligned(struct shash_desc *desc, const u8 *data, | 76 | static int shash_update_unaligned(struct shash_desc *desc, const u8 *data, |
| 84 | unsigned int len) | 77 | unsigned int len) |
| 85 | { | 78 | { |
| @@ -88,11 +81,17 @@ static int shash_update_unaligned(struct shash_desc *desc, const u8 *data, | |||
| 88 | unsigned long alignmask = crypto_shash_alignmask(tfm); | 81 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
| 89 | unsigned int unaligned_len = alignmask + 1 - | 82 | unsigned int unaligned_len = alignmask + 1 - |
| 90 | ((unsigned long)data & alignmask); | 83 | ((unsigned long)data & alignmask); |
| 91 | u8 ubuf[shash_align_buffer_size(unaligned_len, alignmask)] | 84 | /* |
| 92 | __aligned_largest; | 85 | * We cannot count on __aligned() working for large values: |
| 86 | * https://patchwork.kernel.org/patch/9507697/ | ||
| 87 | */ | ||
| 88 | u8 ubuf[MAX_ALGAPI_ALIGNMASK * 2]; | ||
| 93 | u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1); | 89 | u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1); |
| 94 | int err; | 90 | int err; |
| 95 | 91 | ||
| 92 | if (WARN_ON(buf + unaligned_len > ubuf + sizeof(ubuf))) | ||
| 93 | return -EINVAL; | ||
| 94 | |||
| 96 | if (unaligned_len > len) | 95 | if (unaligned_len > len) |
| 97 | unaligned_len = len; | 96 | unaligned_len = len; |
| 98 | 97 | ||
| @@ -124,11 +123,17 @@ static int shash_final_unaligned(struct shash_desc *desc, u8 *out) | |||
| 124 | unsigned long alignmask = crypto_shash_alignmask(tfm); | 123 | unsigned long alignmask = crypto_shash_alignmask(tfm); |
| 125 | struct shash_alg *shash = crypto_shash_alg(tfm); | 124 | struct shash_alg *shash = crypto_shash_alg(tfm); |
| 126 | unsigned int ds = crypto_shash_digestsize(tfm); | 125 | unsigned int ds = crypto_shash_digestsize(tfm); |
| 127 | u8 ubuf[shash_align_buffer_size(ds, alignmask)] | 126 | /* |
| 128 | __aligned_largest; | 127 | * We cannot count on __aligned() working for large values: |
| 128 | * https://patchwork.kernel.org/patch/9507697/ | ||
| 129 | */ | ||
| 130 | u8 ubuf[MAX_ALGAPI_ALIGNMASK + HASH_MAX_DIGESTSIZE]; | ||
| 129 | u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1); | 131 | u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1); |
| 130 | int err; | 132 | int err; |
| 131 | 133 | ||
| 134 | if (WARN_ON(buf + ds > ubuf + sizeof(ubuf))) | ||
| 135 | return -EINVAL; | ||
| 136 | |||
| 132 | err = shash->final(desc, buf); | 137 | err = shash->final(desc, buf); |
| 133 | if (err) | 138 | if (err) |
| 134 | goto out; | 139 | goto out; |
