diff options
-rw-r--r-- | fs/nfs/idmap.c | 2 | ||||
-rw-r--r-- | include/linux/key.h | 1 | ||||
-rw-r--r-- | net/dns_resolver/dns_query.c | 1 | ||||
-rw-r--r-- | security/keys/keyctl.c | 15 |
4 files changed, 18 insertions, 1 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 567983d2c0eb..b7458d77f511 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -282,6 +282,8 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen, | |||
282 | desc, "", 0, idmap); | 282 | desc, "", 0, idmap); |
283 | mutex_unlock(&idmap->idmap_mutex); | 283 | mutex_unlock(&idmap->idmap_mutex); |
284 | } | 284 | } |
285 | if (!IS_ERR(rkey)) | ||
286 | set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); | ||
285 | 287 | ||
286 | kfree(desc); | 288 | kfree(desc); |
287 | return rkey; | 289 | return rkey; |
diff --git a/include/linux/key.h b/include/linux/key.h index 017b0826642f..e37a4d807185 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -170,6 +170,7 @@ struct key { | |||
170 | #define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ | 170 | #define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ |
171 | #define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ | 171 | #define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ |
172 | #define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ | 172 | #define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ |
173 | #define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */ | ||
173 | 174 | ||
174 | /* the key type and key description string | 175 | /* the key type and key description string |
175 | * - the desc is used to match a key against search criteria | 176 | * - the desc is used to match a key against search criteria |
diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c index 9acec61f5433..9a32f55cf9b9 100644 --- a/net/dns_resolver/dns_query.c +++ b/net/dns_resolver/dns_query.c | |||
@@ -129,6 +129,7 @@ int dns_query(const char *type, const char *name, size_t namelen, | |||
129 | } | 129 | } |
130 | 130 | ||
131 | down_read(&rkey->sem); | 131 | down_read(&rkey->sem); |
132 | set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); | ||
132 | rkey->perm |= KEY_USR_VIEW; | 133 | rkey->perm |= KEY_USR_VIEW; |
133 | 134 | ||
134 | ret = key_validate(rkey); | 135 | ret = key_validate(rkey); |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index cd5bd0cef25d..609f8d326ddc 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -404,12 +404,25 @@ long keyctl_invalidate_key(key_serial_t id) | |||
404 | key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH); | 404 | key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH); |
405 | if (IS_ERR(key_ref)) { | 405 | if (IS_ERR(key_ref)) { |
406 | ret = PTR_ERR(key_ref); | 406 | ret = PTR_ERR(key_ref); |
407 | |||
408 | /* Root is permitted to invalidate certain special keys */ | ||
409 | if (capable(CAP_SYS_ADMIN)) { | ||
410 | key_ref = lookup_user_key(id, 0, 0); | ||
411 | if (IS_ERR(key_ref)) | ||
412 | goto error; | ||
413 | if (test_bit(KEY_FLAG_ROOT_CAN_INVAL, | ||
414 | &key_ref_to_ptr(key_ref)->flags)) | ||
415 | goto invalidate; | ||
416 | goto error_put; | ||
417 | } | ||
418 | |||
407 | goto error; | 419 | goto error; |
408 | } | 420 | } |
409 | 421 | ||
422 | invalidate: | ||
410 | key_invalidate(key_ref_to_ptr(key_ref)); | 423 | key_invalidate(key_ref_to_ptr(key_ref)); |
411 | ret = 0; | 424 | ret = 0; |
412 | 425 | error_put: | |
413 | key_ref_put(key_ref); | 426 | key_ref_put(key_ref); |
414 | error: | 427 | error: |
415 | kleave(" = %ld", ret); | 428 | kleave(" = %ld", ret); |