summaryrefslogtreecommitdiff
path: root/Documentation/security
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/security')
-rw-r--r--Documentation/security/keys/core.rst217
-rw-r--r--Documentation/security/keys/request-key.rst57
2 files changed, 189 insertions, 85 deletions
diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst
index 9521c4207f01..1b3c907980ad 100644
--- a/Documentation/security/keys/core.rst
+++ b/Documentation/security/keys/core.rst
@@ -57,9 +57,9 @@ Each key has a number of attributes:
type provides an operation to perform a match between the description on a
key and a criterion string.
- * Each key has an owner user ID, a group ID and a permissions mask. These
- are used to control what a process may do to a key from userspace, and
- whether a kernel service will be able to find the key.
+ * Each key has an owner user ID, a group ID and an ACL. These are used to
+ control what a process may do to a key from userspace, and whether a
+ kernel service will be able to find the key.
* Each key can be set to expire at a specific time by the key type's
instantiation function. Keys can also be immortal.
@@ -198,43 +198,110 @@ The key service provides a number of features besides keys:
Key Access Permissions
======================
-Keys have an owner user ID, a group access ID, and a permissions mask. The mask
-has up to eight bits each for possessor, user, group and other access. Only
-six of each set of eight bits are defined. These permissions granted are:
+Keys have an owner user ID, a group ID and an ACL. The ACL is made up of a
+sequence of ACEs that each contain three elements:
- * View
+ * The type of subject.
+ * The subject.
- This permits a key or keyring's attributes to be viewed - including key
- type and description.
+ These two together indicate the subject to whom the permits are granted.
+ The type can be one of:
- * Read
+ * ``KEY_ACE_SUBJ_STANDARD``
- This permits a key's payload to be viewed or a keyring's list of linked
- keys.
+ The subject is a standard 'macro' type. The subject can be one of:
+
+ * ``KEY_ACE_EVERYONE``
+
+ The permits are granted to everyone. It replaces the old 'other'
+ type on the assumption that you wouldn't grant a permission to other
+ that you you wouldn't grant to everyone else.
+
+ * ``KEY_ACE_OWNER``
+
+ The permits are granted to the owner of the key (key->uid).
+
+ * ``KEY_ACE_GROUP``
+
+ The permits are granted to the key's group (key->gid).
+
+ * ``KEY_ACE_POSSESSOR``
+
+ The permits are granted to anyone who possesses the key.
+
+ * The set of permits granted to the subject. These include:
+
+ * ``KEY_ACE_VIEW``
+
+ This permits a key or keyring's attributes to be viewed - including the
+ key type and description.
+
+ * ``KEY_ACE_READ``
+
+ This permits a key's payload to be viewed or a keyring's list of linked
+ keys.
+
+ * ``KEY_ACE_WRITE``
+
+ This permits a key's payload to be instantiated or updated, or it allows
+ a link to be added to or removed from a keyring.
+
+ * ``KEY_ACE_SEARCH``
+
+ This permits keyrings to be searched and keys to be found. Searches can
+ only recurse into nested keyrings that have search permission set.
+
+ * ``KEY_ACE_LINK``
+
+ This permits a key or keyring to be linked to. To create a link from a
+ keyring to a key, a process must have Write permission on the keyring
+ and Link permission on the key.
+
+ * ``KEY_ACE_SET_SECURITY``
+
+ This permits a key's UID, GID and permissions mask to be changed.
- * Write
+ * ``KEY_ACE_INVAL``
- This permits a key's payload to be instantiated or updated, or it allows a
- link to be added to or removed from a keyring.
+ This permits a key to be invalidated with KEYCTL_INVALIDATE.
- * Search
+ * ``KEY_ACE_REVOKE``
- This permits keyrings to be searched and keys to be found. Searches can
- only recurse into nested keyrings that have search permission set.
+ This permits a key to be revoked with KEYCTL_REVOKE.
- * Link
+ * ``KEY_ACE_JOIN``
- This permits a key or keyring to be linked to. To create a link from a
- keyring to a key, a process must have Write permission on the keyring and
- Link permission on the key.
+ This permits a keyring to be joined as a session by
+ KEYCTL_JOIN_SESSION_KEYRING or KEYCTL_SESSION_TO_PARENT.
- * Set Attribute
+ * ``KEY_ACE_CLEAR``
- This permits a key's UID, GID and permissions mask to be changed.
+ This permits a keyring to be cleared.
For changing the ownership, group ID or permissions mask, being the owner of
the key or having the sysadmin capability is sufficient.
+The legacy KEYCTL_SETPERM and KEYCTL_DESCRIBE functions can only see/generate
+View, Read, Write, Search, Link and SetAttr permits, and do this for each of
+possessor, user, group and other permission sets as a 32-bit flag mask. These
+will be approximated/inferred:
+
+ SETPERM Permit Implied ACE Permit
+ =============== =======================
+ Search Inval, Join
+ Write Revoke, Clear
+ Setattr Set Security, Revoke
+
+ ACE Permit Described as
+ =============== =======================
+ Inval Search
+ Join Search
+ Revoke Write (unless Setattr)
+ Clear write
+ Set Security Setattr
+
+'Other' will be approximated as/inferred from the 'Everyone' subject.
+
SELinux Support
===============
@@ -433,6 +500,10 @@ The main syscalls are:
/sbin/request-key will be invoked in an attempt to obtain a key. The
callout_info string will be passed as an argument to the program.
+ To link a key into the destination keyring the key must grant link
+ permission on the key to the caller and the keyring must grant write
+ permission.
+
See also Documentation/security/keys/request-key.rst.
@@ -577,6 +648,27 @@ The keyctl syscall functions are:
added.
+ * Move a key from one keyring to another::
+
+ long keyctl(KEYCTL_MOVE,
+ key_serial_t id,
+ key_serial_t from_ring_id,
+ key_serial_t to_ring_id,
+ unsigned int flags);
+
+ Move the key specified by "id" from the keyring specified by
+ "from_ring_id" to the keyring specified by "to_ring_id". If the two
+ keyrings are the same, nothing is done.
+
+ "flags" can have KEYCTL_MOVE_EXCL set in it to cause the operation to fail
+ with EEXIST if a matching key exists in the destination keyring, otherwise
+ such a key will be replaced.
+
+ A process must have link permission on the key for this function to be
+ successful and write permission on both keyrings. Any errors that can
+ occur from KEYCTL_LINK also apply on the destination keyring here.
+
+
* Unlink a key or keyring from another keyring::
long keyctl(KEYCTL_UNLINK, key_serial_t keyring, key_serial_t key);
@@ -1059,7 +1151,8 @@ payload contents" for more information.
struct key *request_key(const struct key_type *type,
const char *description,
- const char *callout_info);
+ const char *callout_info,
+ struct key_acl *acl);
This is used to request a key or keyring with a description that matches
the description specified according to the key type's match_preparse()
@@ -1074,52 +1167,50 @@ payload contents" for more information.
If successful, the key will have been attached to the default keyring for
implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
+ If a key is created, it will be given the specified ACL.
+
See also Documentation/security/keys/request-key.rst.
+ * To search for a key in a specific domain, call:
+
+ struct key *request_key_tag(const struct key_type *type,
+ const char *description,
+ struct key_tag *domain_tag,
+ const char *callout_info,
+ struct key_acl *acl);
+
+ This is identical to request_key(), except that a domain tag may be
+ specifies that causes search algorithm to only match keys matching that
+ tag. The domain_tag may be NULL, specifying a global domain that is
+ separate from any nominated domain.
+
+
* To search for a key, passing auxiliary data to the upcaller, call::
struct key *request_key_with_auxdata(const struct key_type *type,
const char *description,
+ struct key_tag *domain_tag,
const void *callout_info,
size_t callout_len,
- void *aux);
-
- This is identical to request_key(), except that the auxiliary data is
- passed to the key_type->request_key() op if it exists, and the callout_info
- is a blob of length callout_len, if given (the length may be 0).
-
-
- * A key can be requested asynchronously by calling one of::
-
- struct key *request_key_async(const struct key_type *type,
- const char *description,
- const void *callout_info,
- size_t callout_len);
-
- or::
-
- struct key *request_key_async_with_auxdata(const struct key_type *type,
- const char *description,
- const char *callout_info,
- size_t callout_len,
- void *aux);
+ void *aux,
+ struct key_acl *acl);
- which are asynchronous equivalents of request_key() and
- request_key_with_auxdata() respectively.
+ This is identical to request_key_tag(), except that the auxiliary data is
+ passed to the key_type->request_key() op if it exists, and the
+ callout_info is a blob of length callout_len, if given (the length may be
+ 0).
- These two functions return with the key potentially still under
- construction. To wait for construction completion, the following should be
- called::
- int wait_for_key_construction(struct key *key, bool intr);
+ * To search for a key under RCU conditions, call::
- The function will wait for the key to finish being constructed and then
- invokes key_validate() to return an appropriate value to indicate the state
- of the key (0 indicates the key is usable).
+ struct key *request_key_rcu(const struct key_type *type,
+ const char *description,
+ struct key_tag *domain_tag);
- If intr is true, then the wait can be interrupted by a signal, in which
- case error ERESTARTSYS will be returned.
+ which is similar to request_key_tag() except that it does not check for
+ keys that are under construction and it will not call out to userspace to
+ construct a key if it can't find a match.
* When it is no longer required, the key should be released using::
@@ -1159,11 +1250,13 @@ payload contents" for more information.
key_ref_t keyring_search(key_ref_t keyring_ref,
const struct key_type *type,
- const char *description)
+ const char *description,
+ bool recurse)
- This searches the keyring tree specified for a matching key. Error ENOKEY
- is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful,
- the returned key will need to be released.
+ This searches the specified keyring only (recurse == false) or keyring tree
+ (recurse == true) specified for a matching key. Error ENOKEY is returned
+ upon failure (use IS_ERR/PTR_ERR to determine). If successful, the returned
+ key will need to be released.
The possession attribute from the keyring reference is used to control
access through the permissions mask and is propagated to the returned key
@@ -1174,7 +1267,7 @@ payload contents" for more information.
struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
const struct cred *cred,
- key_perm_t perm,
+ struct key_acl *acl,
struct key_restriction *restrict_link,
unsigned long flags,
struct key *dest);
diff --git a/Documentation/security/keys/request-key.rst b/Documentation/security/keys/request-key.rst
index 600ad67d1707..f356fd06c8d5 100644
--- a/Documentation/security/keys/request-key.rst
+++ b/Documentation/security/keys/request-key.rst
@@ -11,30 +11,32 @@ The process starts by either the kernel requesting a service by calling
struct key *request_key(const struct key_type *type,
const char *description,
- const char *callout_info);
+ const char *callout_info,
+ struct key_acl *acl);
+
+or::
+
+ struct key *request_key_tag(const struct key_type *type,
+ const char *description,
+ const struct key_tag *domain_tag,
+ const char *callout_info,
+ struct key_acl *acl);
or::
struct key *request_key_with_auxdata(const struct key_type *type,
const char *description,
+ const struct key_tag *domain_tag,
const char *callout_info,
size_t callout_len,
- void *aux);
+ void *aux,
+ struct key_acl *acl);
or::
- struct key *request_key_async(const struct key_type *type,
- const char *description,
- const char *callout_info,
- size_t callout_len);
-
-or::
-
- struct key *request_key_async_with_auxdata(const struct key_type *type,
- const char *description,
- const char *callout_info,
- size_t callout_len,
- void *aux);
+ struct key *request_key_rcu(const struct key_type *type,
+ const char *description,
+ const struct key_tag *domain_tag);
Or by userspace invoking the request_key system call::
@@ -48,14 +50,18 @@ does not need to link the key to a keyring to prevent it from being immediately
destroyed. The kernel interface returns a pointer directly to the key, and
it's up to the caller to destroy the key.
-The request_key*_with_auxdata() calls are like the in-kernel request_key*()
-calls, except that they permit auxiliary data to be passed to the upcaller (the
-default is NULL). This is only useful for those key types that define their
-own upcall mechanism rather than using /sbin/request-key.
+The request_key_tag() call is like the in-kernel request_key(), except that it
+also takes a domain tag that allows keys to be separated by namespace and
+killed off as a group.
+
+The request_key_with_auxdata() calls is like the request_key_tag() call, except
+that they permit auxiliary data to be passed to the upcaller (the default is
+NULL). This is only useful for those key types that define their own upcall
+mechanism rather than using /sbin/request-key.
-The two async in-kernel calls may return keys that are still in the process of
-being constructed. The two non-async ones will wait for construction to
-complete first.
+The request_key_rcu() call is like the request_key_tag() call, except that it
+doesn't check for keys that are under construction and doesn't attempt to
+construct missing keys.
The userspace interface links the key to a keyring associated with the process
to prevent the key from going away, and returns the serial number of the key to
@@ -148,7 +154,7 @@ The Search Algorithm
A search of any particular keyring proceeds in the following fashion:
- 1) When the key management code searches for a key (keyring_search_aux) it
+ 1) When the key management code searches for a key (keyring_search_rcu) it
firstly calls key_permission(SEARCH) on the keyring it's starting with,
if this denies permission, it doesn't search further.
@@ -167,6 +173,9 @@ The process stops immediately a valid key is found with permission granted to
use it. Any error from a previous match attempt is discarded and the key is
returned.
+When request_key() is invoked, if CONFIG_KEYS_REQUEST_CACHE=y, a per-task
+one-key cache is first checked for a match.
+
When search_process_keyrings() is invoked, it performs the following searches
until one succeeds:
@@ -186,7 +195,9 @@ until one succeeds:
c) The calling process's session keyring is searched.
The moment one succeeds, all pending errors are discarded and the found key is
-returned.
+returned. If CONFIG_KEYS_REQUEST_CACHE=y, then that key is placed in the
+per-task cache, displacing the previous key. The cache is cleared on exit or
+just prior to resumption of userspace.
Only if all these fail does the whole thing fail with the highest priority
error. Note that several errors may have come from LSM.