The KEYS subsystem in the Linux kernel before 4.4 allows local users to
gain privileges or cause a denial of service (BUG) via crafted keyctl
commands that negatively instantiate a key, related to
security/keys/encrypted-keys/encrypted.c, security/keys/trusted.c, and
The KEYS subsystem in the Linux kernel through 4.13.7 mishandles use of
add_key for a key that already exists but is uninstantiated, which allows
local users to cause a denial of service (NULL pointer dereference and
system crash) or possibly have unspecified other impact via a crafted
These patches have been tested with the reproducers for both CVEs as
well as the test-ecryptfs-utils.py QRT test which makes use of the
kernel keyring when setting up and decrypting user's home directories.
If a user key gets negatively instantiated, an error code is cached in the
payload area. A negatively instantiated key may be then be positively
instantiated by updating it with valid data. However, the ->update key
type method must be aware that the error code may be there.
The following may be used to trigger the bug in the user key type:
keyctl request2 user user "" @u
keyctl add user user "a" @u
Currently, when passed a key that already exists, add_key() will call the
key's ->update() method if such exists. But this is heavily broken in the
case where the key is uninstantiated because it doesn't call
__key_instantiate_and_link(). Consequently, it doesn't do most of the
things that are supposed to happen when the key is instantiated, such as
setting the instantiation state, clearing KEY_FLAG_USER_CONSTRUCT and
awakening tasks waiting on it, and incrementing key->user->nikeys.
It also never takes key_construction_mutex, which means that
->instantiate() can run concurrently with ->update() on the same key. In
the case of the "user" and "logon" key types this causes a memory leak, at
best. Maybe even worse, the ->update() methods of the "encrypted" and
"trusted" key types actually just dereference a NULL pointer when passed an
Change key_create_or_update() to wait interruptibly for the key to finish
construction before continuing.
This patch only affects *uninstantiated* keys. For now we still allow a
negatively instantiated key to be updated (thereby positively
instantiating it), although that's broken too (the next patch fixes it)
and I'm not sure that anyone actually uses that functionality either.
Here is a simple reproducer for the bug using the "encrypted" key type
(requires CONFIG_ENCRYPTED_KEYS=y), though as noted above the bug
pertained to more than just the "encrypted" key type: