|
@@ -73,13 +73,6 @@ int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(crypto_shash_setkey);
|
|
|
|
|
|
-static inline unsigned int shash_align_buffer_size(unsigned len,
|
|
|
- unsigned long mask)
|
|
|
-{
|
|
|
- typedef u8 __aligned_largest u8_aligned;
|
|
|
- return len + (mask & ~(__alignof__(u8_aligned) - 1));
|
|
|
-}
|
|
|
-
|
|
|
static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
|
|
|
unsigned int len)
|
|
|
{
|
|
@@ -88,11 +81,17 @@ static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
|
|
|
unsigned long alignmask = crypto_shash_alignmask(tfm);
|
|
|
unsigned int unaligned_len = alignmask + 1 -
|
|
|
((unsigned long)data & alignmask);
|
|
|
- u8 ubuf[shash_align_buffer_size(unaligned_len, alignmask)]
|
|
|
- __aligned_largest;
|
|
|
+ /*
|
|
|
+ * We cannot count on __aligned() working for large values:
|
|
|
+ * https://patchwork.kernel.org/patch/9507697/
|
|
|
+ */
|
|
|
+ u8 ubuf[MAX_ALGAPI_ALIGNMASK * 2];
|
|
|
u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
|
|
|
int err;
|
|
|
|
|
|
+ if (WARN_ON(buf + unaligned_len > ubuf + sizeof(ubuf)))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
if (unaligned_len > len)
|
|
|
unaligned_len = len;
|
|
|
|
|
@@ -124,11 +123,17 @@ static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
|
|
|
unsigned long alignmask = crypto_shash_alignmask(tfm);
|
|
|
struct shash_alg *shash = crypto_shash_alg(tfm);
|
|
|
unsigned int ds = crypto_shash_digestsize(tfm);
|
|
|
- u8 ubuf[shash_align_buffer_size(ds, alignmask)]
|
|
|
- __aligned_largest;
|
|
|
+ /*
|
|
|
+ * We cannot count on __aligned() working for large values:
|
|
|
+ * https://patchwork.kernel.org/patch/9507697/
|
|
|
+ */
|
|
|
+ u8 ubuf[MAX_ALGAPI_ALIGNMASK + HASH_MAX_DIGESTSIZE];
|
|
|
u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
|
|
|
int err;
|
|
|
|
|
|
+ if (WARN_ON(buf + ds > ubuf + sizeof(ubuf)))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
err = shash->final(desc, buf);
|
|
|
if (err)
|
|
|
goto out;
|