]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
crypto: asymmetric_keys - prevent overflow in asymmetric_key_generate_id
authorThorsten Blum <thorsten.blum@linux.dev>
Mon, 13 Oct 2025 11:40:10 +0000 (13:40 +0200)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 23 Oct 2025 04:55:42 +0000 (12:55 +0800)
Use check_add_overflow() to guard against potential integer overflows
when adding the binary blob lengths and the size of an asymmetric_key_id
structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a
possible buffer overflow when copying data from potentially malicious
X.509 certificate fields that can be arbitrarily large, such as ASN.1
INTEGER serial numbers, issuer names, etc.

Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling")
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/asymmetric_keys/asymmetric_type.c

index ba2d9d1ea235a7133131397d3ab496cf9eb597e2..348966ea2175c9f470a7c87f1906f4d3747743c1 100644 (file)
@@ -11,6 +11,7 @@
 #include <crypto/public_key.h>
 #include <linux/seq_file.h>
 #include <linux/module.h>
+#include <linux/overflow.h>
 #include <linux/slab.h>
 #include <linux/ctype.h>
 #include <keys/system_keyring.h>
@@ -141,12 +142,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
                                                     size_t len_2)
 {
        struct asymmetric_key_id *kid;
-
-       kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2,
-                     GFP_KERNEL);
+       size_t kid_sz;
+       size_t len;
+
+       if (check_add_overflow(len_1, len_2, &len))
+               return ERR_PTR(-EOVERFLOW);
+       if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz))
+               return ERR_PTR(-EOVERFLOW);
+       kid = kmalloc(kid_sz, GFP_KERNEL);
        if (!kid)
                return ERR_PTR(-ENOMEM);
-       kid->len = len_1 + len_2;
+       kid->len = len;
        memcpy(kid->data, val_1, len_1);
        memcpy(kid->data + len_1, val_2, len_2);
        return kid;