diff options
Diffstat (limited to 'Documentation/security')
-rw-r--r-- | Documentation/security/keys/core.rst | 217 | ||||
-rw-r--r-- | Documentation/security/keys/request-key.rst | 57 |
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. |