keys: Make the KEY_NEED_* perms an enum rather than a mask
authorDavid Howells <dhowells@redhat.com>
Tue, 12 May 2020 14:16:29 +0000 (15:16 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 19 May 2020 14:42:22 +0000 (15:42 +0100)
commit8c0637e950d68933a67f7438f779d79b049b5e5c
tree3a0e17ac6d3dac7dad70f78b9e3e69cb6a2d4e7f
parente7d553d69cf63aec7de0f38fed49ccbb30922e1e
keys: Make the KEY_NEED_* perms an enum rather than a mask

Since the meaning of combining the KEY_NEED_* constants is undefined, make
it so that you can't do that by turning them into an enum.

The enum is also given some extra values to represent special
circumstances, such as:

 (1) The '0' value is reserved and causes a warning to trap the parameter
     being unset.

 (2) The key is to be unlinked and we require no permissions on it, only
     the keyring, (this replaces the KEY_LOOKUP_FOR_UNLINK flag).

 (3) An override due to CAP_SYS_ADMIN.

 (4) An override due to an instantiation token being present.

 (5) The permissions check is being deferred to later key_permission()
     calls.

The extra values give the opportunity for LSMs to audit these situations.

[Note: This really needs overhauling so that lookup_user_key() tells
 key_task_permission() and the LSM what operation is being done and leaves
 it to those functions to decide how to map that onto the available
 permits.  However, I don't really want to make these change in the middle
 of the notifications patchset.]

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
cc: Paul Moore <paul@paul-moore.com>
cc: Stephen Smalley <stephen.smalley.work@gmail.com>
cc: Casey Schaufler <casey@schaufler-ca.com>
cc: keyrings@vger.kernel.org
cc: selinux@vger.kernel.org
include/linux/key.h
include/linux/security.h
security/keys/internal.h
security/keys/keyctl.c
security/keys/permission.c
security/keys/process_keys.c
security/security.c
security/selinux/hooks.c
security/smack/smack_lsm.c