mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-28 12:53:14 +01:00
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.
Fixes: 7e70cb4978 ("keys: add new key-type encrypted")
Cc: [email protected]
Assisted-by: GitHub-Copilot:claude-opus-4.6
Signed-off-by: Cen Zhang <[email protected]>
Signed-off-by: Francis Perron <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: R Nageswara Sastry <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jarkko Sakkinen <[email protected]>
This commit is contained in:
1 parent
114f00d738
commit
8697c431e2
1 file changed
+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);
|
||||
|
||||
ret = key_payload_reserve(key, payload_datalen + datablob_len
|
||||
+ HASH_SIZE + 1);
|
||||
if (check_add_overflow(datablob_len,
|
||||
payload_datalen + HASH_SIZE + 1,
|
||||
&payload_totallen))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
Reference in new issue
Block a user