[PATCH v3 1/3] KEYS: Expand key->{datalen,quotalen} to unsigned int

From: Jarkko Sakkinen

Date: Mon Oct 19 2026 - 21:39:55 EST


In key_alloc() and key_payload_reserve(), key->quotalen and key->datalen
can receive values larger than USHRT_MAX.

Example:

keyctl new_session >/dev/null
owner=$(keyctl newring owner @s)
keeper=$(keyctl newring keeper @s)

for ((i=0; i<16384; i++)); do
key=$(keyctl add user "k$i" x "$keeper")
keyctl link "$key" "$owner"
done

awk -v uid="$(id -u):" '$1 == uid {print $NF}' /proc/key-users
keyctl clear "$owner"
awk -v uid="$(id -u):" '$1 == uid {print $NF}' /proc/key-users

Because key->datalen wraps around 65535, the quota refunded upon clearing
is truncated, causing quota bytes to leak in /proc/key-users.

Change the types of key->datalen and key->quotalen from unsigned short to
unsigned int so that they can carry the full payload length without
truncation.

Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reviewed-by: David Howells <dhowells@xxxxxxxxxx>
Signed-off-by: Jarkko Sakkinen <jarkko@xxxxxxxxxx>
---
include/linux/key.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/key.h b/include/linux/key.h
index e40b5267658f..26139c3adf62 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -216,8 +216,8 @@ struct key {
kuid_t uid;
kgid_t gid;
key_perm_t perm; /* access permissions */
- unsigned short quotalen; /* length added to quota */
- unsigned short datalen; /* payload data length
+ unsigned int quotalen; /* length added to quota */
+ unsigned int datalen; /* payload data length
* - may not match RCU dereferenced payload
* - payload should contain own length
*/
--
2.47.3