KEYS: encrypted: fix integer overflow of datablob_len
Subsystems (5)
PATCH v3 1/1 KEYS: encrypted: fix integer overflow of datablob_len
encrypted_key_alloc() stores datablob_len in a u16. It is computed from multiple string and payload lengths. If the result exceeds U16_MAX, the assignment truncates the allocation size. KASAN reports a 32760-byte slab-out-of-bounds write when __ekey_init() copies the master key description into the undersized buffer.
The total payload length stored in key->datalen is also a u16. Use check_add_overflow() to reject values that do not fit either destination, and use kzalloc_flex() for the flexible-array allocation.
---
Changes in v3:
- Describe the bounds using u16 and U16_MAX and simplify the commit message.
- Include the KASAN-reported write size.
- Remove organization names from the author and sign-off identities.
- Remove the unnecessary off-list discussion note.
- Use [email protected].
- No code changes.
security/keys/encrypted-keys/encrypted.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
security/keys/encrypted-keys/encrypted.c +14 -6
@@ -19,6 +19,7 @@#include <linux/parser.h> #include <linux/string.h> #include <linux/err.h> +#include <linux/overflow.h> #include <keys/user-type.h> #include <keys/trusted-type.h> #include <keys/encrypted-type.h>
@@ -579,6 +580,7 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, {struct encrypted_key_payload *epayload =NULL ;unsigned short datablob_len; +unsigned short payload_totallen;unsigned short decrypted_datalen;unsigned short payload_datalen;unsigned int encrypted_datalen;
@@ -632,16 +634,22 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, encrypted_datalen =roundup (decrypted_datalen, blksize); - datablob_len = format_len +1 +strlen (master_desc) +1 - +strlen (datalen) +1 + ivsize +1 + encrypted_datalen; +if (check_add_overflow (format_len +1 +strlen (master_desc) +1 + +strlen (datalen) +1 + ivsize +1 , + encrypted_datalen, &datablob_len)) +return ERR_PTR (-EINVAL ); + +if (check_add_overflow (datablob_len, + payload_datalen +HASH_SIZE +1 , + &payload_totallen)) +return ERR_PTR (-EINVAL ); - ret =key_payload_reserve (key, payload_datalen + datablob_len - +HASH_SIZE +1 ); + ret =key_payload_reserve (key, payload_totallen);if (ret <0 )return ERR_PTR (ret); - epayload =kzalloc (sizeof (*epayload) + payload_datalen + - datablob_len +HASH_SIZE +1 ,GFP_KERNEL ); + epayload =kzalloc_flex (*epayload, payload_data, payload_totallen, +GFP_KERNEL );if (!epayload)return ERR_PTR (-ENOMEM );
base-commit: 893e11787f78e43b534e252249ac3fff4d1333f8
Signature · 1 line
2.55.0
Quoted 79 lines · Cen Zhang
encrypted_key_alloc()storesdatablob_lenin a u16. It is computed from multiple string and payload lengths. If the result exceedsU16_MAX, the assignment truncates the allocation size. KASAN reports a 32760-byte slab-out-of-bounds write when__ekey_init()copies the master key description into the undersized buffer.The total payload length stored in
key->datalenis also a u16. Usecheck_add_overflow()to reject values that do not fit either destination, and usekzalloc_flex()for the flexible-array allocation.Fixes 7e70cb497850 ("keys: add new key-type encrypted")Assisted-by GitHub-Copilot:claude-opus-4.6Signed-off-by Cen Zhang <[email protected]>Signed-off-by Francis Perron <[email protected]>---
Changes in v3:
- Describe the bounds using u16 andU16_MAXand simplify the commit message.
- Include the KASAN-reported write size.
- Remove organization names from the author and sign-off identities.
- Remove the unnecessary off-list discussion note.
- Use [email protected].
- No code changes.security/keys/encrypted-keys/encrypted.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)security/keys/encrypted-keys/encrypted.c +14
-6@@ -19,6 +19,7 @@#include <linux/parser.h> #include <linux/string.h> #include <linux/err.h> +#include <linux/overflow.h> #include <keys/user-type.h> #include <keys/trusted-type.h> #include <keys/encrypted-type.h> @@ -579,6 +580,7 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, {struct encrypted_key_payload *epayload =NULL ;unsigned short datablob_len; +unsigned short payload_totallen;unsigned short decrypted_datalen;unsigned short payload_datalen;unsigned int encrypted_datalen;@@ -632,16 +634,22 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, encrypted_datalen =roundup (decrypted_datalen, blksize); - datablob_len = format_len +1 +strlen (master_desc) +1 - +strlen (datalen) +1 + ivsize +1 + encrypted_datalen; +if (check_add_overflow (format_len +1 +strlen (master_desc) +1 + +strlen (datalen) +1 + ivsize +1 , + encrypted_datalen, &datablob_len)) +return ERR_PTR (-EINVAL ); + +if (check_add_overflow (datablob_len, + payload_datalen +HASH_SIZE +1 , + &payload_totallen)) +return ERR_PTR (-EINVAL ); - ret =key_payload_reserve (key, payload_datalen + datablob_len - +HASH_SIZE +1 ); + ret =key_payload_reserve (key, payload_totallen);if (ret <0 )return ERR_PTR (ret); - epayload =kzalloc (sizeof (*epayload) + payload_datalen + - datablob_len +HASH_SIZE +1 ,GFP_KERNEL ); + epayload =kzalloc_flex (*epayload, payload_data, payload_totallen, +GFP_KERNEL );if (!epayload)return ERR_PTR (-ENOMEM );
Quoted 3 lines
base-commit:
893e11787f78e43b534e252249ac3fff4d1333f8Signature · 1 line
2.55.0
Thanks!
BR, Jarkko
Quoted 10 lines · Cen Zhang
encrypted_key_alloc()storesdatablob_lenin a u16. It is computed from multiple string and payload lengths. If the result exceedsU16_MAX, the assignment truncates the allocation size. KASAN reports a 32760-byte slab-out-of-bounds write when__ekey_init()copies the master key description into the undersized buffer.The total payload length stored in
key->datalenis also a u16. Usecheck_add_overflow()to reject values that do not fit either destination, and usekzalloc_flex()for the flexible-array allocation.
Quoted 6 lines
Fixes 7e70cb497850 ("keys: add new key-type encrypted")Assisted-by GitHub-Copilot:claude-opus-4.6Signed-off-by Cen Zhang <[email protected]>Signed-off-by Francis Perron <[email protected]>
System: ppc64le LPAR (IBM POWER), Linux 7.3-rc2
Quoted 64 lines
---
Changes in v3:
- Describe the bounds using u16 andU16_MAXand simplify the commit message.
- Include the KASAN-reported write size.
- Remove organization names from the author and sign-off identities.
- Remove the unnecessary off-list discussion note.
- Use [email protected].
- No code changes.security/keys/encrypted-keys/encrypted.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)security/keys/encrypted-keys/encrypted.c +14
-6@@ -19,6 +19,7 @@#include <linux/parser.h> #include <linux/string.h> #include <linux/err.h> +#include <linux/overflow.h> #include <keys/user-type.h> #include <keys/trusted-type.h> #include <keys/encrypted-type.h> @@ -579,6 +580,7 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, {struct encrypted_key_payload *epayload =NULL ;unsigned short datablob_len; +unsigned short payload_totallen;unsigned short decrypted_datalen;unsigned short payload_datalen;unsigned int encrypted_datalen;@@ -632,16 +634,22 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, encrypted_datalen =roundup (decrypted_datalen, blksize); - datablob_len = format_len +1 +strlen (master_desc) +1 - +strlen (datalen) +1 + ivsize +1 + encrypted_datalen; +if (check_add_overflow (format_len +1 +strlen (master_desc) +1 + +strlen (datalen) +1 + ivsize +1 , + encrypted_datalen, &datablob_len)) +return ERR_PTR (-EINVAL ); + +if (check_add_overflow (datablob_len, + payload_datalen +HASH_SIZE +1 , + &payload_totallen)) +return ERR_PTR (-EINVAL ); - ret =key_payload_reserve (key, payload_datalen + datablob_len - +HASH_SIZE +1 ); + ret =key_payload_reserve (key, payload_totallen);if (ret <0 )return ERR_PTR (ret); - epayload =kzalloc (sizeof (*epayload) + payload_datalen + - datablob_len +HASH_SIZE +1 ,GFP_KERNEL ); + epayload =kzalloc_flex (*epayload, payload_data, payload_totallen, +GFP_KERNEL );if (!epayload)return ERR_PTR (-ENOMEM );base-commit:
893e11787f78e43b534e252249ac3fff4d1333f8
Signature · 2 lines
Thanks and Regards R.Nageswara Sastry
Quoted 79 lines · R Nageswara Sastry
Quoted 10 lines · Cen Zhang
encrypted_key_alloc()storesdatablob_lenin a u16. It is computed from multiple string and payload lengths. If the result exceedsU16_MAX, the assignment truncates the allocation size. KASAN reports a 32760-byte slab-out-of-bounds write when__ekey_init()copies the master key description into the undersized buffer.The total payload length stored in
key->datalenis also a u16. Usecheck_add_overflow()to reject values that do not fit either destination, and usekzalloc_flex()for the flexible-array allocation.Quoted 6 lines
Fixes 7e70cb497850 ("keys: add new key-type encrypted")Assisted-by GitHub-Copilot:claude-opus-4.6Signed-off-by Cen Zhang <[email protected]>Signed-off-by Francis Perron <[email protected]>Tested-by R Nageswara Sastry <[email protected]>System: ppc64le LPAR (IBM POWER), Linux 7.3-rc2
Quoted 58 lines
---
Changes in v3:
- Describe the bounds using u16 andU16_MAXand simplify the commit message.
- Include the KASAN-reported write size.
- Remove organization names from the author and sign-off identities.
- Remove the unnecessary off-list discussion note.
- Use [email protected].
- No code changes.security/keys/encrypted-keys/encrypted.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)security/keys/encrypted-keys/encrypted.c +14
-6@@ -19,6 +19,7 @@#include <linux/parser.h> #include <linux/string.h> #include <linux/err.h> +#include <linux/overflow.h> #include <keys/user-type.h> #include <keys/trusted-type.h> #include <keys/encrypted-type.h> @@ -579,6 +580,7 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, {struct encrypted_key_payload *epayload =NULL ;unsigned short datablob_len; +unsigned short payload_totallen;unsigned short decrypted_datalen;unsigned short payload_datalen;unsigned int encrypted_datalen;@@ -632,16 +634,22 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, encrypted_datalen =roundup (decrypted_datalen, blksize); - datablob_len = format_len +1 +strlen (master_desc) +1 - +strlen (datalen) +1 + ivsize +1 + encrypted_datalen; +if (check_add_overflow (format_len +1 +strlen (master_desc) +1 + +strlen (datalen) +1 + ivsize +1 , + encrypted_datalen, &datablob_len)) +return ERR_PTR (-EINVAL ); + +if (check_add_overflow (datablob_len, + payload_datalen +HASH_SIZE +1 , + &payload_totallen)) +return ERR_PTR (-EINVAL ); - ret =key_payload_reserve (key, payload_datalen + datablob_len - +HASH_SIZE +1 ); + ret =key_payload_reserve (key, payload_totallen);if (ret <0 )return ERR_PTR (ret); - epayload =kzalloc (sizeof (*epayload) + payload_datalen + - datablob_len +HASH_SIZE +1 ,GFP_KERNEL ); + epayload =kzalloc_flex (*epayload, payload_data, payload_totallen, +GFP_KERNEL );if (!epayload)return ERR_PTR (-ENOMEM );
Quoted 6 lines
Quoted 1 line
base-commit:
893e11787f78e43b534e252249ac3fff4d1333f8Signature · 2 lines
Thanks and Regards R.Nageswara Sastry
BR, Jarkko