Skip to content

Commit

Permalink
KEYS: Allow special keys (eg. DNS results) to be invalidated by CAP_S…
Browse files Browse the repository at this point in the history
…YS_ADMIN

Special kernel keys, such as those used to hold DNS results for AFS, CIFS and
NFS and those used to hold idmapper results for NFS, used to be
'invalidateable' with key_revoke().  However, since the default permissions for
keys were reduced:

	Commit: 96b5c8f
	KEYS: Reduce initial permissions on keys

it has become impossible to do this.

Add a key flag (KEY_FLAG_ROOT_CAN_INVAL) that will permit a key to be
invalidated by root.  This should not be used for system keyrings as the
garbage collector will try and remove any invalidate key.  For system keyrings,
KEY_FLAG_ROOT_CAN_CLEAR can be used instead.

After this, from userspace, keyctl_invalidate() and "keyctl invalidate" can be
used by any possessor of CAP_SYS_ADMIN (typically root) to invalidate DNS and
idmapper keys.  Invalidated keys are immediately garbage collected and will be
immediately rerequested if needed again.

Signed-off-by: David Howells <[email protected]>
Tested-by: Steve Dickson <[email protected]>
  • Loading branch information
dhowells committed Jul 17, 2014
1 parent b6b8a37 commit 0c7774a
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 1 deletion.
2 changes: 2 additions & 0 deletions fs/nfs/idmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen,
desc, "", 0, idmap);
mutex_unlock(&idmap->idmap_mutex);
}
if (!IS_ERR(rkey))
set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags);

kfree(desc);
return rkey;
Expand Down
1 change: 1 addition & 0 deletions include/linux/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ struct key {
#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
#define KEY_FLAG_TRUSTED 8 /* set if key is trusted */
#define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */
#define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */

/* the key type and key description string
* - the desc is used to match a key against search criteria
Expand Down
1 change: 1 addition & 0 deletions net/dns_resolver/dns_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ int dns_query(const char *type, const char *name, size_t namelen,
}

down_read(&rkey->sem);
set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags);
rkey->perm |= KEY_USR_VIEW;

ret = key_validate(rkey);
Expand Down
15 changes: 14 additions & 1 deletion security/keys/keyctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,25 @@ long keyctl_invalidate_key(key_serial_t id)
key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
if (IS_ERR(key_ref)) {
ret = PTR_ERR(key_ref);

/* Root is permitted to invalidate certain special keys */
if (capable(CAP_SYS_ADMIN)) {
key_ref = lookup_user_key(id, 0, 0);
if (IS_ERR(key_ref))
goto error;
if (test_bit(KEY_FLAG_ROOT_CAN_INVAL,
&key_ref_to_ptr(key_ref)->flags))
goto invalidate;
goto error_put;
}

goto error;
}

invalidate:
key_invalidate(key_ref_to_ptr(key_ref));
ret = 0;

error_put:
key_ref_put(key_ref);
error:
kleave(" = %ld", ret);
Expand Down

0 comments on commit 0c7774a

Please sign in to comment.