image_aes_decrypt() allocates cipher_len bytes, decrypts into them, and
then reports the plaintext length to its caller as
info->size_unciphered, without relating the two. size_unciphered comes
from the image's 'data-size-unciphered' property, so an image can claim
a plaintext larger than the buffer that was allocated for it.

fit_image_uncipher() propagates that length as the image size, and
everything downstream - the load, the copy to the entry point - works
from it, reading up to 4 GiB past the end of the decrypted buffer.

Unlike the image data itself, 'data-size-unciphered' is not covered by
the per-image hash or signature, so this is reachable on a signed FIT
whose signature still verifies.

Decryption produces exactly cipher_len bytes, so require the claimed
size to fit within that.

Fixes: 4df3578119b0 ("u-boot: fit: add support to decrypt fit with aes")
Signed-off-by: Pranav Rajendran <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
---
(no changes since v1)

 lib/aes/aes-decrypt.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lib/aes/aes-decrypt.c b/lib/aes/aes-decrypt.c
index 85773a9c4f6..5d616983082 100644
--- a/lib/aes/aes-decrypt.c
+++ b/lib/aes/aes-decrypt.c
@@ -27,6 +27,15 @@ int image_aes_decrypt(struct image_cipher_info *info,
                return -EINVAL;
        }
 
+       /*
+        * Decryption produces exactly cipher_len bytes, so the unciphered
+        * size the image claims cannot be larger than that.
+        */
+       if (info->size_unciphered > cipher_len) {
+               printf("Invalid unciphered size\n");
+               return -EINVAL;
+       }
+
        *data = malloc(cipher_len);
        if (!*data) {
                printf("Can't allocate memory to decrypt\n");
-- 
2.50.1 (Apple Git-155)

Reply via email to