summaryrefslogtreecommitdiffstats
path: root/man2/keyctl.2
diff options
context:
space:
mode:
Diffstat (limited to 'man2/keyctl.2')
-rw-r--r--man2/keyctl.22297
1 files changed, 2297 insertions, 0 deletions
diff --git a/man2/keyctl.2 b/man2/keyctl.2
new file mode 100644
index 0000000..d7bd83d
--- /dev/null
+++ b/man2/keyctl.2
@@ -0,0 +1,2297 @@
+.\" Copyright (C) 2016 Michael Kerrisk <mtk.manpages@gmail.com>
+.\" and Copyright (C) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
+.\" A very few fragments remain from an earlier version of this page
+.\" written by David Howells (dhowells@redhat.com)
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH keyctl 2 2023-05-03 "Linux man-pages 6.05.01"
+.SH NAME
+keyctl \- manipulate the kernel's key management facility
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.PP
+Alternatively, Linux Key Management Utilities
+.RI ( libkeyutils ", " \-lkeyutils );
+see VERSIONS.
+.SH SYNOPSIS
+.nf
+.BR "#include <linux/keyctl.h>" " /* Definition of " KEY* " constants */"
+.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */"
+.B #include <unistd.h>
+.PP
+.BI "long syscall(SYS_keyctl, int " operation ", unsigned long " arg2 ,
+.BI " unsigned long " arg3 ", unsigned long " arg4 ,
+.BI " unsigned long " arg5 );
+.fi
+.PP
+.IR Note :
+glibc provides no wrapper for
+.BR keyctl (),
+necessitating the use of
+.BR syscall (2).
+.SH DESCRIPTION
+.BR keyctl ()
+allows user-space programs to perform key manipulation.
+.PP
+The operation performed by
+.BR keyctl ()
+is determined by the value of the
+.I operation
+argument.
+Each of these operations is wrapped by the
+.I libkeyutils
+library (provided by the
+.I keyutils
+package) into individual functions (noted below)
+to permit the compiler to check types.
+.PP
+The permitted values for
+.I operation
+are:
+.TP
+.BR KEYCTL_GET_KEYRING_ID " (since Linux 2.6.10)"
+Map a special key ID to a real key ID for this process.
+.IP
+This operation looks up the special key whose ID is provided in
+.I arg2
+(cast to
+.IR key_serial_t ).
+If the special key is found,
+the ID of the corresponding real key is returned as the function result.
+The following values may be specified in
+.IR arg2 :
+.RS
+.TP
+.B KEY_SPEC_THREAD_KEYRING
+This specifies the calling thread's thread-specific keyring.
+See
+.BR thread\-keyring (7).
+.TP
+.B KEY_SPEC_PROCESS_KEYRING
+This specifies the caller's process-specific keyring.
+See
+.BR process\-keyring (7).
+.TP
+.B KEY_SPEC_SESSION_KEYRING
+This specifies the caller's session-specific keyring.
+See
+.BR session\-keyring (7).
+.TP
+.B KEY_SPEC_USER_KEYRING
+This specifies the caller's UID-specific keyring.
+See
+.BR user\-keyring (7).
+.TP
+.B KEY_SPEC_USER_SESSION_KEYRING
+This specifies the caller's UID-session keyring.
+See
+.BR user\-session\-keyring (7).
+.TP
+.BR KEY_SPEC_REQKEY_AUTH_KEY " (since Linux 2.6.16)"
+.\" commit b5f545c880a2a47947ba2118b2509644ab7a2969
+This specifies the authorization key created by
+.BR request_key (2)
+and passed to the process it spawns to generate a key.
+This key is available only in a
+.BR request\-key (8)-style
+program that was passed an authorization key by the kernel and
+ceases to be available once the requested key has been instantiated; see
+.BR request_key (2).
+.TP
+.BR KEY_SPEC_REQUESTOR_KEYRING " (since Linux 2.6.29)"
+.\" commit 8bbf4976b59fc9fc2861e79cab7beb3f6d647640
+This specifies the key ID for the
+.BR request_key (2)
+destination keyring.
+This keyring is available only in a
+.BR request\-key (8)-style
+program that was passed an authorization key by the kernel and
+ceases to be available once the requested key has been instantiated; see
+.BR request_key (2).
+.RE
+.IP
+The behavior if the key specified in
+.I arg2
+does not exist depends on the value of
+.I arg3
+(cast to
+.IR int ).
+If
+.I arg3
+contains a nonzero value, then\[em]if it is appropriate to do so
+(e.g., when looking up the user, user-session, or session key)\[em]a new key
+is created and its real key ID returned as the function result.
+.\" The keyctl_get_keyring_ID.3 page says that a new key
+.\" "will be created *if it is appropriate to do so**. What is the
+.\" determiner for appropriate?
+.\" David Howells: Some special keys such as KEY_SPEC_REQKEY_AUTH_KEY
+.\" wouldn't get created but user/user-session/session keyring would
+.\" be created.
+Otherwise, the operation fails with the error
+.BR ENOKEY .
+.IP
+If a valid key ID is specified in
+.IR arg2 ,
+and the key exists, then this operation simply returns the key ID.
+If the key does not exist, the call fails with error
+.BR ENOKEY .
+.IP
+The caller must have
+.I search
+permission on a keyring in order for it to be found.
+.IP
+The arguments
+.I arg4
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_get_keyring_ID (3).
+.TP
+.BR KEYCTL_JOIN_SESSION_KEYRING " (since Linux 2.6.10)"
+Replace the session keyring this process subscribes to with
+a new session keyring.
+.\" This may be useful in conjunction with some sort of
+.\" session management framework that is employed by the application.
+.IP
+If
+.I arg2
+is NULL,
+an anonymous keyring with the description "_ses" is created
+and the process is subscribed to that keyring as its session keyring,
+displacing the previous session keyring.
+.IP
+Otherwise,
+.I arg2
+(cast to
+.IR "char\ *" )
+is treated as the description (name) of a keyring,
+and the behavior is as follows:
+.RS
+.IP \[bu] 3
+If a keyring with a matching description exists,
+the process will attempt to subscribe to that keyring
+as its session keyring if possible;
+if that is not possible, an error is returned.
+In order to subscribe to the keyring,
+the caller must have
+.I search
+permission on the keyring.
+.IP \[bu]
+If a keyring with a matching description does not exist,
+then a new keyring with the specified description is created,
+and the process is subscribed to that keyring as its session keyring.
+.RE
+.IP
+The arguments
+.IR arg3 ,
+.IR arg4 ,
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_join_session_keyring (3).
+.TP
+.BR KEYCTL_UPDATE " (since Linux 2.6.10)"
+Update a key's data payload.
+.IP
+The
+.I arg2
+argument (cast to
+.IR key_serial_t )
+specifies the ID of the key to be updated.
+The
+.I arg3
+argument (cast to
+.IR "void\ *" )
+points to the new payload and
+.I arg4
+(cast to
+.IR size_t )
+contains the new payload size in bytes.
+.IP
+The caller must have
+.I write
+permission on the key specified and the key type must support updating.
+.IP
+A negatively instantiated key (see the description of
+.BR KEYCTL_REJECT )
+can be positively instantiated with this operation.
+.IP
+The
+.I arg5
+argument is ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_update (3).
+.TP
+.BR KEYCTL_REVOKE " (since Linux 2.6.10)"
+Revoke the key with the ID provided in
+.I arg2
+(cast to
+.IR key_serial_t ).
+The key is scheduled for garbage collection;
+it will no longer be findable,
+and will be unavailable for further operations.
+Further attempts to use the key will fail with the error
+.BR EKEYREVOKED .
+.IP
+The caller must have
+.I write
+or
+.I setattr
+permission on the key.
+.\" Keys with the KEY_FLAG_KEEP bit set cause an EPERM
+.\" error for KEYCTL_REVOKE. Does this need to be documented?
+.\" David Howells: No significance for user space.
+.IP
+The arguments
+.IR arg3 ,
+.IR arg4 ,
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_revoke (3).
+.TP
+.BR KEYCTL_CHOWN " (since Linux 2.6.10)"
+Change the ownership (user and group ID) of a key.
+.IP
+The
+.I arg2
+argument (cast to
+.IR key_serial_t )
+contains the key ID.
+The
+.I arg3
+argument (cast to
+.IR uid_t )
+contains the new user ID (or \-1 in case the user ID shouldn't be changed).
+The
+.I arg4
+argument (cast to
+.IR gid_t )
+contains the new group ID (or \-1 in case the group ID shouldn't be changed).
+.IP
+The key must grant the caller
+.I setattr
+permission.
+.IP
+For the UID to be changed, or for the GID to be changed to a group
+the caller is not a member of, the caller must have the
+.B CAP_SYS_ADMIN
+capability (see
+.BR capabilities (7)).
+.IP
+If the UID is to be changed, the new user must have sufficient
+quota to accept the key.
+The quota deduction will be removed from the old user
+to the new user should the UID be changed.
+.IP
+The
+.I arg5
+argument is ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_chown (3).
+.TP
+.BR KEYCTL_SETPERM " (since Linux 2.6.10)"
+Change the permissions of the key with the ID provided in the
+.I arg2
+argument (cast to
+.IR key_serial_t )
+to the permissions provided in the
+.I arg3
+argument (cast to
+.IR key_perm_t ).
+.IP
+If the caller doesn't have the
+.B CAP_SYS_ADMIN
+capability, it can change permissions only for the keys it owns.
+(More precisely: the caller's filesystem UID must match the UID of the key.)
+.IP
+The key must grant
+.I setattr
+permission to the caller
+.I regardless
+of the caller's capabilities.
+.\" FIXME Above, is it really intended that a privileged process can't
+.\" override the lack of the 'setattr' permission?
+.IP
+The permissions in
+.I arg3
+specify masks of available operations
+for each of the following user categories:
+.RS
+.TP
+.IR possessor " (since Linux 2.6.14)"
+.\" commit 664cceb0093b755739e56572b836a99104ee8a75
+This is the permission granted to a process that possesses the key
+(has it attached searchably to one of the process's keyrings);
+see
+.BR keyrings (7).
+.TP
+.I user
+This is the permission granted to a process
+whose filesystem UID matches the UID of the key.
+.TP
+.I group
+This is the permission granted to a process
+whose filesystem GID or any of its supplementary GIDs
+matches the GID of the key.
+.TP
+.I other
+This is the permission granted to other processes
+that do not match the
+.I user
+and
+.I group
+categories.
+.RE
+.IP
+The
+.IR user ,
+.IR group ,
+and
+.I other
+categories are exclusive: if a process matches the
+.I user
+category, it will not receive permissions granted in the
+.I group
+category; if a process matches the
+.I user
+or
+.I group
+category, then it will not receive permissions granted in the
+.I other
+category.
+.IP
+The
+.I possessor
+category grants permissions that are cumulative with the grants from the
+.IR user ,
+.IR group ,
+or
+.I other
+category.
+.IP
+Each permission mask is eight bits in size,
+with only six bits currently used.
+The available permissions are:
+.RS
+.TP
+.I view
+This permission allows reading attributes of a key.
+.IP
+This permission is required for the
+.B KEYCTL_DESCRIBE
+operation.
+.IP
+The permission bits for each category are
+.BR KEY_POS_VIEW ,
+.BR KEY_USR_VIEW ,
+.BR KEY_GRP_VIEW ,
+and
+.BR KEY_OTH_VIEW .
+.TP
+.I read
+This permission allows reading a key's payload.
+.IP
+This permission is required for the
+.B KEYCTL_READ
+operation.
+.IP
+The permission bits for each category are
+.BR KEY_POS_READ ,
+.BR KEY_USR_READ ,
+.BR KEY_GRP_READ ,
+and
+.BR KEY_OTH_READ .
+.TP
+.I write
+This permission allows update or instantiation of a key's payload.
+For a keyring, it allows keys to be linked and unlinked from the keyring,
+.IP
+This permission is required for the
+.BR KEYCTL_UPDATE ,
+.BR KEYCTL_REVOKE ,
+.BR KEYCTL_CLEAR ,
+.BR KEYCTL_LINK ,
+and
+.B KEYCTL_UNLINK
+operations.
+.IP
+The permission bits for each category are
+.BR KEY_POS_WRITE ,
+.BR KEY_USR_WRITE ,
+.BR KEY_GRP_WRITE ,
+and
+.BR KEY_OTH_WRITE .
+.TP
+.I search
+This permission allows keyrings to be searched and keys to be found.
+Searches can recurse only into nested keyrings that have
+.I search
+permission set.
+.IP
+This permission is required for the
+.BR KEYCTL_GET_KEYRING_ID ,
+.BR KEYCTL_JOIN_SESSION_KEYRING ,
+.BR KEYCTL_SEARCH ,
+and
+.B KEYCTL_INVALIDATE
+operations.
+.IP
+The permission bits for each category are
+.BR KEY_POS_SEARCH ,
+.BR KEY_USR_SEARCH ,
+.BR KEY_GRP_SEARCH ,
+and
+.BR KEY_OTH_SEARCH .
+.TP
+.I link
+This permission allows a key or keyring to be linked to.
+.IP
+This permission is required for the
+.B KEYCTL_LINK
+and
+.B KEYCTL_SESSION_TO_PARENT
+operations.
+.IP
+The permission bits for each category are
+.BR KEY_POS_LINK ,
+.BR KEY_USR_LINK ,
+.BR KEY_GRP_LINK ,
+and
+.BR KEY_OTH_LINK .
+.TP
+.IR setattr " (since Linux 2.6.15)."
+This permission allows a key's UID, GID, and permissions mask to be changed.
+.IP
+This permission is required for the
+.BR KEYCTL_REVOKE ,
+.BR KEYCTL_CHOWN ,
+and
+.B KEYCTL_SETPERM
+operations.
+.IP
+The permission bits for each category are
+.BR KEY_POS_SETATTR ,
+.BR KEY_USR_SETATTR ,
+.BR KEY_GRP_SETATTR ,
+and
+.BR KEY_OTH_SETATTR .
+.RE
+.IP
+As a convenience, the following macros are defined as masks for
+all of the permission bits in each of the user categories:
+.BR KEY_POS_ALL ,
+.BR KEY_USR_ALL ,
+.BR KEY_GRP_ALL ,
+and
+.BR KEY_OTH_ALL .
+.IP
+The
+.I arg4
+and
+.I arg5
+arguments are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_setperm (3).
+.TP
+.BR KEYCTL_DESCRIBE " (since Linux 2.6.10)"
+Obtain a string describing the attributes of a specified key.
+.IP
+The ID of the key to be described is specified in
+.I arg2
+(cast to
+.IR key_serial_t ).
+The descriptive string is returned in the buffer pointed to by
+.I arg3
+(cast to
+.IR char\~* );
+.I arg4
+(cast to
+.IR size_t )
+specifies the size of that buffer in bytes.
+.IP
+The key must grant the caller
+.I view
+permission.
+.IP
+The returned string is null-terminated and
+contains the following information about the key:
+.IP
+.in +4n
+.IR type ; uid ; gid ; perm ; description
+.in
+.IP
+In the above,
+.I type
+and
+.I description
+are strings,
+.I uid
+and
+.I gid
+are decimal strings, and
+.I perm
+is a hexadecimal permissions mask.
+The descriptive string is written with the following format:
+.IP
+.in +4n
+.EX
+%s;%d;%d;%08x;%s
+.EE
+.in
+.IP
+.B Note: the intention is that the descriptive string should
+.B be extensible in future kernel versions.
+In particular, the
+.I description
+field will not contain semicolons;
+.\" FIXME But, the kernel does not enforce the requirement
+.\" that the key description contains no semicolons!
+.\" So, user space has no guarantee here??
+.\" Either something more needs to be said here,
+.\" or a kernel fix is required.
+it should be parsed by working backwards from the end of the string
+to find the last semicolon.
+This allows future semicolon-delimited fields to be inserted
+in the descriptive string in the future.
+.IP
+Writing to the buffer is attempted only when
+.I arg3
+is non-NULL and the specified buffer size
+is large enough to accept the descriptive string
+(including the terminating null byte).
+.\" Function commentary says it copies up to buflen bytes, but see the
+.\" (buffer && buflen >= ret) condition in keyctl_describe_key() in
+.\" security/keyctl.c
+In order to determine whether the buffer size was too small,
+check to see if the return value of the operation is greater than
+.IR arg4 .
+.IP
+The
+.I arg5
+argument is ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_describe (3).
+.TP
+.B KEYCTL_CLEAR
+Clear the contents of (i.e., unlink all keys from) a keyring.
+.IP
+The ID of the key
+(which must be of keyring type)
+.\" or the error ENOTDIR results
+is provided in
+.I arg2
+(cast to
+.IR key_serial_t ).
+.\" According to Documentation/security/keys.txt:
+.\" This function can also be used to clear special kernel keyrings if they
+.\" are appropriately marked if the user has CAP_SYS_ADMIN capability. The
+.\" DNS resolver cache keyring is an example of this.
+.IP
+The caller must have
+.I write
+permission on the keyring.
+.IP
+The arguments
+.IR arg3 ,
+.IR arg4 ,
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_clear (3).
+.TP
+.BR KEYCTL_LINK " (since Linux 2.6.10)"
+Create a link from a keyring to a key.
+.IP
+The key to be linked is specified in
+.I arg2
+(cast to
+.IR key_serial_t );
+the keyring is specified in
+.I arg3
+(cast to
+.IR key_serial_t ).
+.IP
+If a key with the same type and description is already linked in the keyring,
+then that key is displaced from the keyring.
+.IP
+Before creating the link,
+the kernel checks the nesting of the keyrings and returns appropriate errors
+if the link would produce a cycle
+or if the nesting of keyrings would be too deep
+(The limit on the nesting of keyrings is determined by the kernel constant
+.BR KEYRING_SEARCH_MAX_DEPTH ,
+defined with the value 6, and is necessary to prevent overflows
+on the kernel stack when recursively searching keyrings).
+.IP
+The caller must have
+.I link
+permission on the key being added and
+.I write
+permission on the keyring.
+.IP
+The arguments
+.I arg4
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_link (3).
+.TP
+.BR KEYCTL_UNLINK " (since Linux 2.6.10)"
+Unlink a key from a keyring.
+.IP
+The ID of the key to be unlinked is specified in
+.I arg2
+(cast to
+.IR key_serial_t );
+the ID of the keyring from which it is to be unlinked is specified in
+.I arg3
+(cast to
+.IR key_serial_t ).
+.IP
+If the key is not currently linked into the keyring, an error results.
+.IP
+The caller must have
+.I write
+permission on the keyring from which the key is being removed.
+.IP
+If the last link to a key is removed,
+then that key will be scheduled for destruction.
+.IP
+The arguments
+.I arg4
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_unlink (3).
+.TP
+.BR KEYCTL_SEARCH " (since Linux 2.6.10)"
+Search for a key in a keyring tree,
+returning its ID and optionally linking it to a specified keyring.
+.IP
+The tree to be searched is specified by passing
+the ID of the head keyring in
+.I arg2
+(cast to
+.IR key_serial_t ).
+The search is performed breadth-first and recursively.
+.IP
+The
+.I arg3
+and
+.I arg4
+arguments specify the key to be searched for:
+.I arg3
+(cast as
+.IR char\~* )
+contains the key type
+(a null-terminated character string up to 32 bytes in size,
+including the terminating null byte), and
+.I arg4
+(cast as
+.IR char\~* )
+contains the description of the key
+(a null-terminated character string up to 4096 bytes in size,
+including the terminating null byte).
+.IP
+The source keyring must grant
+.I search
+permission to the caller.
+When performing the recursive search, only keyrings that grant the caller
+.I search
+permission will be searched.
+Only keys with for which the caller has
+.I search
+permission can be found.
+.IP
+If the key is found, its ID is returned as the function result.
+.IP
+If the key is found and
+.I arg5
+(cast to
+.IR key_serial_t )
+is nonzero, then, subject to the same constraints and rules as
+.BR KEYCTL_LINK ,
+the key is linked into the keyring whose ID is specified in
+.IR arg5 .
+If the destination keyring specified in
+.I arg5
+already contains a link to a key that has the same type and description,
+then that link will be displaced by a link to
+the key found by this operation.
+.IP
+Instead of valid existing keyring IDs, the source
+.RI ( arg2 )
+and destination
+.RI ( arg5 )
+keyrings can be one of the special keyring IDs listed under
+.BR KEYCTL_GET_KEYRING_ID .
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_search (3).
+.TP
+.BR KEYCTL_READ " (since Linux 2.6.10)"
+Read the payload data of a key.
+.IP
+The ID of the key whose payload is to be read is specified in
+.I arg2
+(cast to
+.IR key_serial_t ).
+This can be the ID of an existing key,
+or any of the special key IDs listed for
+.BR KEYCTL_GET_KEYRING_ID .
+.\" including KEY_SPEC_REQKEY_AUTH_KEY
+.IP
+The payload is placed in the buffer pointed by
+.I arg3
+(cast to
+.IR "char\ *" );
+the size of that buffer must be specified in
+.I arg4
+(cast to
+.IR size_t ).
+.IP
+The returned data will be processed for presentation
+according to the key type.
+For example, a keyring will return an array of
+.I key_serial_t
+entries representing the IDs of all the keys that are linked to it.
+The
+.I user
+key type will return its data as is.
+If a key type does not implement this function,
+the operation fails with the error
+.BR EOPNOTSUPP .
+.IP
+If
+.I arg3
+is not NULL,
+as much of the payload data as will fit is copied into the buffer.
+On a successful return,
+the return value is always the total size of the payload data.
+To determine whether the buffer was of sufficient size,
+check to see that the return value is less than or equal to
+the value supplied in
+.IR arg4 .
+.IP
+The key must either grant the caller
+.I read
+permission, or grant the caller
+.I search
+permission when searched for from the process keyrings
+(i.e., the key is possessed).
+.IP
+The
+.I arg5
+argument is ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_read (3).
+.TP
+.BR KEYCTL_INSTANTIATE " (since Linux 2.6.10)"
+(Positively) instantiate an uninstantiated key with a specified payload.
+.IP
+The ID of the key to be instantiated is provided in
+.I arg2
+(cast to
+.IR key_serial_t ).
+.IP
+The key payload is specified in the buffer pointed to by
+.I arg3
+(cast to
+.IR "void\ *");
+the size of that buffer is specified in
+.I arg4
+(cast to
+.IR size_t ).
+.IP
+The payload may be a NULL pointer and the buffer size may be 0
+if this is supported by the key type (e.g., it is a keyring).
+.IP
+The operation may be fail if the payload data is in the wrong format
+or is otherwise invalid.
+.IP
+If
+.I arg5
+(cast to
+.IR key_serial_t )
+is nonzero, then, subject to the same constraints and rules as
+.BR KEYCTL_LINK ,
+the instantiated key is linked into the keyring whose ID specified in
+.IR arg5 .
+.IP
+The caller must have the appropriate authorization key,
+and once the uninstantiated key has been instantiated,
+the authorization key is revoked.
+In other words, this operation is available only from a
+.BR request\-key (8)-style
+program.
+See
+.BR request_key (2)
+for an explanation of uninstantiated keys and key instantiation.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_instantiate (3).
+.TP
+.BR KEYCTL_NEGATE " (since Linux 2.6.10)"
+Negatively instantiate an uninstantiated key.
+.IP
+This operation is equivalent to the call:
+.IP
+.in +4n
+.EX
+keyctl(KEYCTL_REJECT, arg2, arg3, ENOKEY, arg4);
+.EE
+.in
+.IP
+The
+.I arg5
+argument is ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_negate (3).
+.TP
+.BR KEYCTL_SET_REQKEY_KEYRING " (since Linux 2.6.13)"
+Set the default keyring to which implicitly requested keys
+will be linked for this thread, and return the previous setting.
+Implicit key requests are those made by internal kernel components,
+.\" I.e., calls to the kernel's internal request_key() interface,
+.\" which is distinct from the request_key(2) system call (which
+.\" ultimately employs the kernel-internal interface).
+such as can occur when, for example, opening files
+on an AFS or NFS filesystem.
+Setting the default keyring also has an effect when requesting
+a key from user space; see
+.BR request_key (2)
+for details.
+.IP
+The
+.I arg2
+argument (cast to
+.IR int )
+should contain one of the following values,
+to specify the new default keyring:
+.RS
+.TP
+.B KEY_REQKEY_DEFL_NO_CHANGE
+Don't change the default keyring.
+This can be used to discover the current default keyring
+(without changing it).
+.TP
+.B KEY_REQKEY_DEFL_DEFAULT
+This selects the default behaviour,
+which is to use the thread-specific keyring if there is one,
+otherwise the process-specific keyring if there is one,
+otherwise the session keyring if there is one,
+otherwise the UID-specific session keyring,
+otherwise the user-specific keyring.
+.TP
+.B KEY_REQKEY_DEFL_THREAD_KEYRING
+Use the thread-specific keyring
+.RB ( thread\-keyring (7))
+as the new default keyring.
+.TP
+.B KEY_REQKEY_DEFL_PROCESS_KEYRING
+Use the process-specific keyring
+.RB ( process\-keyring (7))
+as the new default keyring.
+.TP
+.B KEY_REQKEY_DEFL_SESSION_KEYRING
+Use the session-specific keyring
+.RB ( session\-keyring (7))
+as the new default keyring.
+.TP
+.B KEY_REQKEY_DEFL_USER_KEYRING
+Use the UID-specific keyring
+.RB ( user\-keyring (7))
+as the new default keyring.
+.TP
+.B KEY_REQKEY_DEFL_USER_SESSION_KEYRING
+Use the UID-specific session keyring
+.RB ( user\-session\-keyring (7))
+as the new default keyring.
+.TP
+.BR KEY_REQKEY_DEFL_REQUESTOR_KEYRING " (since Linux 2.6.29)"
+.\" 8bbf4976b59fc9fc2861e79cab7beb3f6d647640
+Use the requestor keyring.
+.\" FIXME The preceding explanation needs to be expanded.
+.\" Is the following correct:
+.\"
+.\" The requestor keyring is the dest_keyring that
+.\" was supplied to a call to request_key(2)?
+.\"
+.\" David Howells said: to be checked
+.RE
+.IP
+All other values are invalid.
+.\" (including the still-unsupported KEY_REQKEY_DEFL_GROUP_KEYRING)
+.IP
+The arguments
+.IR arg3 ,
+.IR arg4 ,
+and
+.I arg5
+are ignored.
+.IP
+The setting controlled by this operation is inherited by the child of
+.BR fork (2)
+and preserved across
+.BR execve (2).
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_set_reqkey_keyring (3).
+.TP
+.BR KEYCTL_SET_TIMEOUT " (since Linux 2.6.16)"
+Set a timeout on a key.
+.IP
+The ID of the key is specified in
+.I arg2
+(cast to
+.IR key_serial_t ).
+The timeout value, in seconds from the current time,
+is specified in
+.I arg3
+(cast to
+.IR "unsigned int" ).
+The timeout is measured against the realtime clock.
+.IP
+Specifying the timeout value as 0 clears any existing timeout on the key.
+.IP
+The
+.I /proc/keys
+file displays the remaining time until each key will expire.
+(This is the only method of discovering the timeout on a key.)
+.IP
+The caller must either have the
+.I setattr
+permission on the key
+or hold an instantiation authorization token for the key (see
+.BR request_key (2)).
+.IP
+The key and any links to the key will be
+automatically garbage collected after the timeout expires.
+Subsequent attempts to access the key will then fail with the error
+.BR EKEYEXPIRED .
+.IP
+This operation cannot be used to set timeouts on revoked, expired,
+or negatively instantiated keys.
+.IP
+The arguments
+.I arg4
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_set_timeout (3).
+.TP
+.BR KEYCTL_ASSUME_AUTHORITY " (since Linux 2.6.16)"
+Assume (or divest) the authority for the calling thread
+to instantiate a key.
+.IP
+The
+.I arg2
+argument (cast to
+.IR key_serial_t )
+specifies either a nonzero key ID to assume authority,
+or the value 0 to divest authority.
+.IP
+If
+.I arg2
+is nonzero, then it specifies the ID of an uninstantiated key for which
+authority is to be assumed.
+That key can then be instantiated using one of
+.BR KEYCTL_INSTANTIATE ,
+.BR KEYCTL_INSTANTIATE_IOV ,
+.BR KEYCTL_REJECT ,
+or
+.BR KEYCTL_NEGATE .
+Once the key has been instantiated,
+the thread is automatically divested of authority to instantiate the key.
+.IP
+Authority over a key can be assumed only if the calling thread has present
+in its keyrings the authorization key that is
+associated with the specified key.
+(In other words, the
+.B KEYCTL_ASSUME_AUTHORITY
+operation is available only from a
+.BR request\-key (8)-style
+program; see
+.BR request_key (2)
+for an explanation of how this operation is used.)
+The caller must have
+.I search
+permission on the authorization key.
+.IP
+If the specified key has a matching authorization key,
+then the ID of that key is returned.
+The authorization key can be read
+.RB ( KEYCTL_READ )
+to obtain the callout information passed to
+.BR request_key (2).
+.IP
+If the ID given in
+.I arg2
+is 0, then the currently assumed authority is cleared (divested),
+and the value 0 is returned.
+.IP
+The
+.B KEYCTL_ASSUME_AUTHORITY
+mechanism allows a program such as
+.BR request\-key (8)
+to assume the necessary authority to instantiate a new uninstantiated key
+that was created as a consequence of a call to
+.BR request_key (2).
+For further information, see
+.BR request_key (2)
+and the kernel source file
+.IR Documentation/security/keys\-request\-key.txt .
+.IP
+The arguments
+.IR arg3 ,
+.IR arg4 ,
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_assume_authority (3).
+.TP
+.BR KEYCTL_GET_SECURITY " (since Linux 2.6.26)"
+.\" commit 70a5bb72b55e82fbfbf1e22cae6975fac58a1e2d
+Get the LSM (Linux Security Module) security label of the specified key.
+.IP
+The ID of the key whose security label is to be fetched is specified in
+.I arg2
+(cast to
+.IR key_serial_t ).
+The security label (terminated by a null byte)
+will be placed in the buffer pointed to by
+.I arg3
+argument (cast to
+.IR "char\ *" );
+the size of the buffer must be provided in
+.I arg4
+(cast to
+.IR size_t ).
+.IP
+If
+.I arg3
+is specified as NULL or the buffer size specified in
+.I arg4
+is too small, the full size of the security label string
+(including the terminating null byte)
+is returned as the function result,
+and nothing is copied to the buffer.
+.IP
+The caller must have
+.I view
+permission on the specified key.
+.IP
+The returned security label string will be rendered in a form appropriate
+to the LSM in force.
+For example, with SELinux, it may look like:
+.IP
+.in +4n
+.EX
+unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+.EE
+.in
+.IP
+If no LSM is currently in force,
+then an empty string is placed in the buffer.
+.IP
+The
+.I arg5
+argument is ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the functions
+.BR keyctl_get_security (3)
+and
+.BR keyctl_get_security_alloc (3).
+.TP
+.BR KEYCTL_SESSION_TO_PARENT " (since Linux 2.6.32)"
+.\" commit ee18d64c1f632043a02e6f5ba5e045bb26a5465f
+Replace the session keyring to which the
+.I parent
+of the calling process
+subscribes with the session keyring of the calling process.
+.\" What is the use case for KEYCTL_SESSION_TO_PARENT?
+.\" David Howells: the Process Authentication Groups people requested this,
+.\" but then didn't use it; maybe there are no users.
+.IP
+The keyring will be replaced in the parent process at the point
+where the parent next transitions from kernel space to user space.
+.IP
+The keyring must exist and must grant the caller
+.I link
+permission.
+The parent process must be single-threaded and have
+the same effective ownership as this process
+and must not be set-user-ID or set-group-ID.
+The UID of the parent process's existing session keyring (f it has one),
+as well as the UID of the caller's session keyring
+much match the caller's effective UID.
+.IP
+The fact that it is the parent process that is affected by this operation
+allows a program such as the shell to start a child process that
+uses this operation to change the shell's session keyring.
+(This is what the
+.BR keyctl (1)
+.B new_session
+command does.)
+.IP
+The arguments
+.IR arg2 ,
+.IR arg3 ,
+.IR arg4 ,
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_session_to_parent (3).
+.TP
+.BR KEYCTL_REJECT " (since Linux 2.6.39)"
+.\" commit fdd1b94581782a2ddf9124414e5b7a5f48ce2f9c
+Mark a key as negatively instantiated and set an expiration timer
+on the key.
+This operation provides a superset of the functionality of the earlier
+.B KEYCTL_NEGATE
+operation.
+.IP
+The ID of the key that is to be negatively instantiated is specified in
+.I arg2
+(cast to
+.IR key_serial_t ).
+The
+.I arg3
+(cast to
+.IR "unsigned int" )
+argument specifies the lifetime of the key, in seconds.
+The
+.I arg4
+argument (cast to
+.IR "unsigned int" )
+specifies the error to be returned when a search hits this key;
+typically, this is one of
+.BR EKEYREJECTED ,
+.BR EKEYREVOKED ,
+or
+.BR EKEYEXPIRED .
+.IP
+If
+.I arg5
+(cast to
+.IR key_serial_t )
+is nonzero, then, subject to the same constraints and rules as
+.BR KEYCTL_LINK ,
+the negatively instantiated key is linked into the keyring
+whose ID is specified in
+.IR arg5 .
+.IP
+The caller must have the appropriate authorization key.
+In other words, this operation is available only from a
+.BR request\-key (8)-style
+program.
+See
+.BR request_key (2).
+.IP
+The caller must have the appropriate authorization key,
+and once the uninstantiated key has been instantiated,
+the authorization key is revoked.
+In other words, this operation is available only from a
+.BR request\-key (8)-style
+program.
+See
+.BR request_key (2)
+for an explanation of uninstantiated keys and key instantiation.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_reject (3).
+.TP
+.BR KEYCTL_INSTANTIATE_IOV " (since Linux 2.6.39)"
+.\" commit ee009e4a0d4555ed522a631bae9896399674f063
+Instantiate an uninstantiated key with a payload specified
+via a vector of buffers.
+.IP
+This operation is the same as
+.BR KEYCTL_INSTANTIATE ,
+but the payload data is specified as an array of
+.I iovec
+structures (see
+.BR iovec (3type)).
+.IP
+The pointer to the payload vector is specified in
+.I arg3
+(cast as
+.IR "const struct iovec\~*" ).
+The number of items in the vector is specified in
+.I arg4
+(cast as
+.IR "unsigned int" ).
+.IP
+The
+.I arg2
+(key ID)
+and
+.I arg5
+(keyring ID)
+are interpreted as for
+.BR KEYCTL_INSTANTIATE .
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_instantiate_iov (3).
+.TP
+.BR KEYCTL_INVALIDATE " (since Linux 3.5)"
+.\" commit fd75815f727f157a05f4c96b5294a4617c0557da
+Mark a key as invalid.
+.IP
+The ID of the key to be invalidated is specified in
+.I arg2
+(cast to
+.IR key_serial_t ).
+.IP
+To invalidate a key,
+the caller must have
+.I search
+permission on the key.
+.\" CAP_SYS_ADMIN is permitted to invalidate certain special keys
+.IP
+This operation marks the key as invalid
+and schedules immediate garbage collection.
+The garbage collector removes the invalidated key from all keyrings and
+deletes the key when its reference count reaches zero.
+After this operation,
+the key will be ignored by all searches,
+even if it is not yet deleted.
+.IP
+Keys that are marked invalid become invisible to normal key operations
+immediately, though they are still visible in
+.I /proc/keys
+(marked with an 'i' flag)
+until they are actually removed.
+.IP
+The arguments
+.IR arg3 ,
+.IR arg4 ,
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_invalidate (3).
+.TP
+.BR KEYCTL_GET_PERSISTENT " (since Linux 3.13)"
+.\" commit f36f8c75ae2e7d4da34f4c908cebdb4aa42c977e
+Get the persistent keyring
+.RB ( persistent\-keyring (7))
+for a specified user and link it to a specified keyring.
+.IP
+The user ID is specified in
+.I arg2
+(cast to
+.IR uid_t ).
+If the value \-1 is specified, the caller's real user ID is used.
+The ID of the destination keyring is specified in
+.I arg3
+(cast to
+.IR key_serial_t ).
+.IP
+The caller must have the
+.B CAP_SETUID
+capability in its user namespace in order to fetch the persistent keyring
+for a user ID that does not match either the real or effective user ID
+of the caller.
+.IP
+If the call is successful,
+a link to the persistent keyring is added to the keyring
+whose ID was specified in
+.IR arg3 .
+.IP
+The caller must have
+.I write
+permission on the keyring.
+.IP
+The persistent keyring will be created by the kernel
+if it does not yet exist.
+.IP
+Each time the
+.B KEYCTL_GET_PERSISTENT
+operation is performed, the persistent keyring will
+have its expiration timeout reset to the value in:
+.IP
+.in +4n
+.EX
+/proc/sys/kernel/keys/persistent_keyring_expiry
+.EE
+.in
+.IP
+Should the timeout be reached,
+the persistent keyring will be removed and
+everything it pins can then be garbage collected.
+.IP
+Persistent keyrings were added in Linux 3.13.
+.IP
+The arguments
+.I arg4
+and
+.I arg5
+are ignored.
+.IP
+This operation is exposed by
+.I libkeyutils
+via the function
+.BR keyctl_get_persistent (3).
+.TP
+.BR KEYCTL_DH_COMPUTE " (since Linux 4.7)"
+.\" commit ddbb41148724367394d0880c516bfaeed127b52e
+Compute a Diffie-Hellman shared secret or public key,
+optionally applying key derivation function (KDF) to the result.
+.IP
+The
+.I arg2
+argument is a pointer to a set of parameters containing
+serial numbers for three
+.I """user"""
+keys used in the Diffie-Hellman calculation,
+packaged in a structure of the following form:
+.IP
+.in +4n
+.EX
+struct keyctl_dh_params {
+ int32_t private; /* The local private key */
+ int32_t prime; /* The prime, known to both parties */
+ int32_t base; /* The base integer: either a shared
+ generator or the remote public key */
+};
+.EE
+.in
+.IP
+Each of the three keys specified in this structure must grant the caller
+.I read
+permission.
+The payloads of these keys are used to calculate the Diffie-Hellman
+result as:
+.IP
+.in +4n
+.EX
+base \[ha] private mod prime
+.EE
+.in
+.IP
+If the base is the shared generator, the result is the local public key.
+If the base is the remote public key, the result is the shared secret.
+.IP
+The
+.I arg3
+argument (cast to
+.IR char\~* )
+points to a buffer where the result of the calculation is placed.
+The size of that buffer is specified in
+.I arg4
+(cast to
+.IR size_t ).
+.IP
+The buffer must be large enough to accommodate the output data,
+otherwise an error is returned.
+If
+.I arg4
+is specified zero,
+in which case the buffer is not used and
+the operation returns the minimum required buffer size
+(i.e., the length of the prime).
+.IP
+Diffie-Hellman computations can be performed in user space,
+but require a multiple-precision integer (MPI) library.
+Moving the implementation into the kernel gives access to
+the kernel MPI implementation,
+and allows access to secure or acceleration hardware.
+.IP
+Adding support for DH computation to the
+.BR keyctl ()
+system call was considered a good fit due to the DH algorithm's use
+for deriving shared keys;
+it also allows the type of the key to determine
+which DH implementation (software or hardware) is appropriate.
+.\" commit f1c316a3ab9d24df6022682422fe897492f2c0c8
+.IP
+If the
+.I arg5
+argument is
+.BR NULL ,
+then the DH result itself is returned.
+Otherwise (since Linux 4.12), it is a pointer to a structure which specifies
+parameters of the KDF operation to be applied:
+.IP
+.in +4n
+.EX
+struct keyctl_kdf_params {
+ char *hashname; /* Hash algorithm name */
+ char *otherinfo; /* SP800\-56A OtherInfo */
+ __u32 otherinfolen; /* Length of otherinfo data */
+ __u32 __spare[8]; /* Reserved */
+};
+.EE
+.in
+.IP
+The
+.I hashname
+field is a null-terminated string which specifies a hash name
+(available in the kernel's crypto API; the list of the hashes available
+is rather tricky to observe; please refer to the
+.UR https://www.kernel.org\:/doc\:/html\:/latest\:/crypto\:/architecture.html
+"Kernel Crypto API Architecture"
+.UE
+documentation for the information regarding how hash names are constructed and
+your kernel's source and configuration regarding what ciphers
+and templates with type
+.B CRYPTO_ALG_TYPE_SHASH
+are available)
+to be applied to DH result in KDF operation.
+.IP
+The
+.I otherinfo
+field is an
+.I OtherInfo
+data as described in SP800-56A section 5.8.1.2 and is algorithm-specific.
+This data is concatenated with the result of DH operation and is provided as
+an input to the KDF operation.
+Its size is provided in the
+.I otherinfolen
+field and is limited by
+.B KEYCTL_KDF_MAX_OI_LEN
+constant that defined in
+.I security/keys/internal.h
+to a value of 64.
+.IP
+The
+.B __spare
+field is currently unused.
+.\" commit 4f9dabfaf8df971f8a3b6aa324f8f817be38d538
+It was ignored until Linux 4.13 (but still should be
+user-addressable since it is copied to the kernel),
+and should contain zeros since Linux 4.13.
+.IP
+The KDF implementation complies with SP800-56A as well
+as with SP800-108 (the counter KDF).
+.IP
+.\" keyutils commit 742c9d7b94051d3b21f9f61a73ed6b5f3544cb82
+.\" keyutils commit d68a981e5db41d059ac782071c35d1e8f3aaf61c
+This operation is exposed by
+.I libkeyutils
+(from
+.I libkeyutils
+1.5.10 onwards) via the functions
+.BR keyctl_dh_compute (3)
+and
+.BR keyctl_dh_compute_alloc (3).
+.TP
+.BR KEYCTL_RESTRICT_KEYRING " (since Linux 4.12)"
+.\" commit 6563c91fd645556c7801748f15bc727c77fcd311
+.\" commit 7228b66aaf723a623e578aa4db7d083bb39546c9
+Apply a key-linking restriction to the keyring with the ID provided in
+.I arg2
+(cast to
+.IR key_serial_t ).
+The caller must have
+.I setattr
+permission on the key.
+If
+.I arg3
+is NULL, any attempt to add a key to the keyring is blocked;
+otherwise it contains a pointer to a string with a key type name and
+.I arg4
+contains a pointer to string that describes the type-specific restriction.
+As of Linux 4.12, only the type "asymmetric" has restrictions defined:
+.RS
+.TP
+.B builtin_trusted
+Allows only keys that are signed by a key linked to the built-in keyring
+(".builtin_trusted_keys").
+.TP
+.B builtin_and_secondary_trusted
+Allows only keys that are signed by a key linked to the secondary keyring
+(".secondary_trusted_keys") or, by extension, a key in a built-in keyring,
+as the latter is linked to the former.
+.TP
+.BI key_or_keyring: key
+.TQ
+.BI key_or_keyring: key :chain
+If
+.I key
+specifies the ID of a key of type "asymmetric",
+then only keys that are signed by this key are allowed.
+.IP
+If
+.I key
+specifies the ID of a keyring,
+then only keys that are signed by a key linked
+to this keyring are allowed.
+.IP
+If ":chain" is specified, keys that are signed by a keys linked to the
+destination keyring (that is, the keyring with the ID specified in the
+.I arg2
+argument) are also allowed.
+.RE
+.IP
+Note that a restriction can be configured only once for the specified keyring;
+once a restriction is set, it can't be overridden.
+.IP
+The argument
+.I arg5
+is ignored.
+.\" FIXME Document KEYCTL_RESTRICT_KEYRING, added in Linux 4.12
+.\" commit 6563c91fd645556c7801748f15bc727c77fcd311
+.\" Author: Mat Martineau <mathew.j.martineau@linux.intel.com>
+.\" See Documentation/security/keys.txt
+.SH RETURN VALUE
+For a successful call, the return value depends on the operation:
+.TP
+.B KEYCTL_GET_KEYRING_ID
+The ID of the requested keyring.
+.TP
+.B KEYCTL_JOIN_SESSION_KEYRING
+The ID of the joined session keyring.
+.TP
+.B KEYCTL_DESCRIBE
+The size of the description (including the terminating null byte),
+irrespective of the provided buffer size.
+.TP
+.B KEYCTL_SEARCH
+The ID of the key that was found.
+.TP
+.B KEYCTL_READ
+The amount of data that is available in the key,
+irrespective of the provided buffer size.
+.TP
+.B KEYCTL_SET_REQKEY_KEYRING
+The ID of the previous default keyring
+to which implicitly requested keys were linked
+(one of
+.BR KEY_REQKEY_DEFL_USER_* ).
+.TP
+.B KEYCTL_ASSUME_AUTHORITY
+Either 0, if the ID given was 0,
+or the ID of the authorization key matching the specified key,
+if a nonzero key ID was provided.
+.TP
+.B KEYCTL_GET_SECURITY
+The size of the LSM security label string
+(including the terminating null byte),
+irrespective of the provided buffer size.
+.TP
+.B KEYCTL_GET_PERSISTENT
+The ID of the persistent keyring.
+.TP
+.B KEYCTL_DH_COMPUTE
+The number of bytes copied to the buffer, or, if
+.I arg4
+is 0, the required buffer size.
+.TP
+All other operations
+Zero.
+.PP
+On error, \-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EACCES
+The requested operation wasn't permitted.
+.TP
+.B EAGAIN
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+and there was an error during crypto module initialization.
+.TP
+.B EDEADLK
+.I operation
+was
+.B KEYCTL_LINK
+and the requested link would result in a cycle.
+.TP
+.B EDEADLK
+.I operation
+was
+.B KEYCTL_RESTRICT_KEYRING
+and the requested keyring restriction would result in a cycle.
+.TP
+.B EDQUOT
+The key quota for the caller's user would be exceeded by creating a key or
+linking it to the keyring.
+.TP
+.B EEXIST
+.I operation
+was
+.B KEYCTL_RESTRICT_KEYRING
+and keyring provided in
+.I arg2
+argument already has a restriction set.
+.TP
+.B EFAULT
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+and one of the following has failed:
+.RS
+.IP \[bu] 3
+copying of the
+.IR "struct keyctl_dh_params" ,
+provided in the
+.I arg2
+argument, from user space;
+.IP \[bu]
+copying of the
+.IR "struct keyctl_kdf_params" ,
+provided in the non-NULL
+.I arg5
+argument, from user space
+(in case kernel supports performing KDF operation on DH operation result);
+.IP \[bu]
+copying of data pointed by the
+.I hashname
+field of the
+.I "struct keyctl_kdf_params"
+from user space;
+.IP \[bu]
+copying of data pointed by the
+.I otherinfo
+field of the
+.I struct keyctl_kdf_params
+from user space if the
+.I otherinfolen
+field was nonzero;
+.IP \[bu]
+copying of the result to user space.
+.RE
+.TP
+.B EINVAL
+.I operation
+was
+.B KEYCTL_SETPERM
+and an invalid permission bit was specified in
+.IR arg3 .
+.TP
+.B EINVAL
+.I operation
+was
+.B KEYCTL_SEARCH
+and the size of the description in
+.I arg4
+(including the terminating null byte) exceeded 4096 bytes.
+.TP
+.B EINVAL
+size of the string (including the terminating null byte) specified in
+.I arg3
+(the key type)
+or
+.I arg4
+(the key description)
+exceeded the limit (32 bytes and 4096 bytes respectively).
+.TP
+.BR EINVAL " (before Linux 4.12)"
+.I operation
+was
+.BR KEYCTL_DH_COMPUTE ,
+argument
+.I arg5
+was non-NULL.
+.TP
+.B EINVAL
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+And the digest size of the hashing algorithm supplied is zero.
+.TP
+.B EINVAL
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+and the buffer size provided is not enough to hold the result.
+Provide 0 as a buffer size in order to obtain the minimum buffer size.
+.TP
+.B EINVAL
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+and the hash name provided in the
+.I hashname
+field of the
+.I struct keyctl_kdf_params
+pointed by
+.I arg5
+argument is too big (the limit is implementation-specific and varies between
+kernel versions, but it is deemed big enough for all valid algorithm names).
+.TP
+.B EINVAL
+.\" commit 4f9dabfaf8df971f8a3b6aa324f8f817be38d538
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+and the
+.I __spare
+field of the
+.I struct keyctl_kdf_params
+provided in the
+.I arg5
+argument contains nonzero values.
+.TP
+.B EKEYEXPIRED
+An expired key was found or specified.
+.TP
+.B EKEYREJECTED
+A rejected key was found or specified.
+.TP
+.B EKEYREVOKED
+A revoked key was found or specified.
+.TP
+.B ELOOP
+.I operation
+was
+.B KEYCTL_LINK
+and the requested link would cause the maximum nesting depth
+for keyrings to be exceeded.
+.TP
+.B EMSGSIZE
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+and the buffer length exceeds
+.B KEYCTL_KDF_MAX_OUTPUT_LEN
+(which is 1024 currently)
+or the
+.I otherinfolen
+field of the
+.I struct keyctl_kdf_parms
+passed in
+.I arg5
+exceeds
+.B KEYCTL_KDF_MAX_OI_LEN
+(which is 64 currently).
+.TP
+.BR ENFILE " (before Linux 3.13)"
+.I operation
+was
+.B KEYCTL_LINK
+and the keyring is full.
+(Before Linux 3.13,
+.\" commit b2a4df200d570b2c33a57e1ebfa5896e4bc81b69
+the available space for storing keyring links was limited to
+a single page of memory; since Linux 3.13, there is no fixed limit.)
+.TP
+.B ENOENT
+.I operation
+was
+.B KEYCTL_UNLINK
+and the key to be unlinked isn't linked to the keyring.
+.TP
+.B ENOENT
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+and the hashing algorithm specified in the
+.I hashname
+field of the
+.I struct keyctl_kdf_params
+pointed by
+.I arg5
+argument hasn't been found.
+.TP
+.B ENOENT
+.I operation
+was
+.B KEYCTL_RESTRICT_KEYRING
+and the type provided in
+.I arg3
+argument doesn't support setting key linking restrictions.
+.TP
+.B ENOKEY
+No matching key was found or an invalid key was specified.
+.TP
+.B ENOKEY
+The value
+.B KEYCTL_GET_KEYRING_ID
+was specified in
+.IR operation ,
+the key specified in
+.I arg2
+did not exist, and
+.I arg3
+was zero (meaning don't create the key if it didn't exist).
+.TP
+.B ENOMEM
+One of kernel memory allocation routines failed during the execution of the
+syscall.
+.TP
+.B ENOTDIR
+A key of keyring type was expected but the ID of a key with
+a different type was provided.
+.TP
+.B EOPNOTSUPP
+.I operation
+was
+.B KEYCTL_READ
+and the key type does not support reading
+(e.g., the type is
+.IR """login""" ).
+.TP
+.B EOPNOTSUPP
+.I operation
+was
+.B KEYCTL_UPDATE
+and the key type does not support updating.
+.TP
+.B EOPNOTSUPP
+.I operation
+was
+.BR KEYCTL_RESTRICT_KEYRING ,
+the type provided in
+.I arg3
+argument was "asymmetric",
+and the key specified in the restriction specification provided in
+.I arg4
+has type other than "asymmetric" or "keyring".
+.TP
+.B EPERM
+.I operation
+was
+.BR KEYCTL_GET_PERSISTENT ,
+.I arg2
+specified a UID other than the calling thread's real or effective UID,
+and the caller did not have the
+.B CAP_SETUID
+capability.
+.TP
+.B EPERM
+.I operation
+was
+.B KEYCTL_SESSION_TO_PARENT
+and either:
+all of the UIDs (GIDs) of the parent process do not match
+the effective UID (GID) of the calling process;
+the UID of the parent's existing session keyring or
+the UID of the caller's session keyring did not match
+the effective UID of the caller;
+the parent process is not single-thread;
+or the parent process is
+.BR init (1)
+or a kernel thread.
+.TP
+.B ETIMEDOUT
+.I operation
+was
+.B KEYCTL_DH_COMPUTE
+and the initialization of crypto modules has timed out.
+.SH VERSIONS
+A wrapper is provided in the
+.I libkeyutils
+library.
+(The accompanying package provides the
+.I <keyutils.h>
+header file.)
+However, rather than using this system call directly,
+you probably want to use the various library functions
+mentioned in the descriptions of individual operations above.
+.SH STANDARDS
+Linux.
+.SH HISTORY
+Linux 2.6.10.
+.SH EXAMPLES
+The program below provide subset of the functionality of the
+.BR request\-key (8)
+program provided by the
+.I keyutils
+package.
+For informational purposes,
+the program records various information in a log file.
+.PP
+As described in
+.BR request_key (2),
+the
+.BR request\-key (8)
+program is invoked with command-line arguments that
+describe a key that is to be instantiated.
+The example program fetches and logs these arguments.
+The program assumes authority to instantiate the requested key,
+and then instantiates that key.
+.PP
+The following shell session demonstrates the use of this program.
+In the session,
+we compile the program and then use it to temporarily replace the standard
+.BR request\-key (8)
+program.
+(Note that temporarily disabling the standard
+.BR request\-key (8)
+program may not be safe on some systems.)
+While our example program is installed,
+we use the example program shown in
+.BR request_key (2)
+to request a key.
+.PP
+.in +4n
+.EX
+$ \fBcc \-o key_instantiate key_instantiate.c \-lkeyutils\fP
+$ \fBsudo mv /sbin/request\-key /sbin/request\-key.backup\fP
+$ \fBsudo cp key_instantiate /sbin/request\-key\fP
+$ \fB./t_request_key user mykey somepayloaddata\fP
+Key ID is 20d035bf
+$ \fBsudo mv /sbin/request\-key.backup /sbin/request\-key\fP
+.EE
+.in
+.PP
+Looking at the log file created by this program,
+we can see the command-line arguments supplied to our example program:
+.PP
+.in +4n
+.EX
+$ \fBcat /tmp/key_instantiate.log\fP
+Time: Mon Nov 7 13:06:47 2016
+\&
+Command line arguments:
+ argv[0]: /sbin/request\-key
+ operation: create
+ key_to_instantiate: 20d035bf
+ UID: 1000
+ GID: 1000
+ thread_keyring: 0
+ process_keyring: 0
+ session_keyring: 256e6a6
+\&
+Key description: user;1000;1000;3f010000;mykey
+Auth key payload: somepayloaddata
+Destination keyring: 256e6a6
+Auth key description: .request_key_auth;1000;1000;0b010000;20d035bf
+.EE
+.in
+.PP
+The last few lines of the above output show that the example program
+was able to fetch:
+.IP \[bu] 3
+the description of the key to be instantiated,
+which included the name of the key
+.RI ( mykey );
+.IP \[bu]
+the payload of the authorization key, which consisted of the data
+.RI ( somepayloaddata )
+passed to
+.BR request_key (2);
+.IP \[bu]
+the destination keyring that was specified in the call to
+.BR request_key (2);
+and
+.IP \[bu]
+the description of the authorization key,
+where we can see that the name of the authorization key matches
+the ID of the key that is to be instantiated
+.RI ( 20d035bf ).
+.PP
+The example program in
+.BR request_key (2)
+specified the destination keyring as
+.BR KEY_SPEC_SESSION_KEYRING .
+By examining the contents of
+.IR /proc/keys ,
+we can see that this was translated to the ID of the destination keyring
+.RI ( 0256e6a6 )
+shown in the log output above;
+we can also see the newly created key with the name
+.I mykey
+and ID
+.IR 20d035bf .
+.PP
+.in +4n
+.EX
+$ \fBcat /proc/keys | egrep \[aq]mykey|256e6a6\[aq]\fP
+0256e6a6 I\-\-Q\-\-\- 194 perm 3f030000 1000 1000 keyring _ses: 3
+20d035bf I\-\-Q\-\-\- 1 perm 3f010000 1000 1000 user mykey: 16
+.EE
+.in
+.SS Program source
+\&
+.\" SRC BEGIN (key_instantiate.c)
+.EX
+/* key_instantiate.c */
+\&
+#include <errno.h>
+#include <keyutils.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+\&
+#ifndef KEY_SPEC_REQUESTOR_KEYRING
+#define KEY_SPEC_REQUESTOR_KEYRING (\-8)
+#endif
+\&
+int
+main(int argc, char *argv[])
+{
+ int akp_size; /* Size of auth_key_payload */
+ int auth_key;
+ char dbuf[256];
+ char auth_key_payload[256];
+ char *operation;
+ FILE *fp;
+ gid_t gid;
+ uid_t uid;
+ time_t t;
+ key_serial_t key_to_instantiate, dest_keyring;
+ key_serial_t thread_keyring, process_keyring, session_keyring;
+\&
+ if (argc != 8) {
+ fprintf(stderr, "Usage: %s op key uid gid thread_keyring "
+ "process_keyring session_keyring\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ fp = fopen("/tmp/key_instantiate.log", "w");
+ if (fp == NULL)
+ exit(EXIT_FAILURE);
+\&
+ setbuf(fp, NULL);
+\&
+ t = time(NULL);
+ fprintf(fp, "Time: %s\en", ctime(&t));
+\&
+ /*
+ * The kernel passes a fixed set of arguments to the program
+ * that it execs; fetch them.
+ */
+ operation = argv[1];
+ key_to_instantiate = atoi(argv[2]);
+ uid = atoi(argv[3]);
+ gid = atoi(argv[4]);
+ thread_keyring = atoi(argv[5]);
+ process_keyring = atoi(argv[6]);
+ session_keyring = atoi(argv[7]);
+\&
+ fprintf(fp, "Command line arguments:\en");
+ fprintf(fp, " argv[0]: %s\en", argv[0]);
+ fprintf(fp, " operation: %s\en", operation);
+ fprintf(fp, " key_to_instantiate: %jx\en",
+ (uintmax_t) key_to_instantiate);
+ fprintf(fp, " UID: %jd\en", (intmax_t) uid);
+ fprintf(fp, " GID: %jd\en", (intmax_t) gid);
+ fprintf(fp, " thread_keyring: %jx\en",
+ (uintmax_t) thread_keyring);
+ fprintf(fp, " process_keyring: %jx\en",
+ (uintmax_t) process_keyring);
+ fprintf(fp, " session_keyring: %jx\en",
+ (uintmax_t) session_keyring);
+ fprintf(fp, "\en");
+\&
+ /*
+ * Assume the authority to instantiate the key named in argv[2].
+ */
+ if (keyctl(KEYCTL_ASSUME_AUTHORITY, key_to_instantiate) == \-1) {
+ fprintf(fp, "KEYCTL_ASSUME_AUTHORITY failed: %s\en",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+\&
+ /*
+ * Fetch the description of the key that is to be instantiated.
+ */
+ if (keyctl(KEYCTL_DESCRIBE, key_to_instantiate,
+ dbuf, sizeof(dbuf)) == \-1) {
+ fprintf(fp, "KEYCTL_DESCRIBE failed: %s\en", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+\&
+ fprintf(fp, "Key description: %s\en", dbuf);
+\&
+ /*
+ * Fetch the payload of the authorization key, which is
+ * actually the callout data given to request_key().
+ */
+ akp_size = keyctl(KEYCTL_READ, KEY_SPEC_REQKEY_AUTH_KEY,
+ auth_key_payload, sizeof(auth_key_payload));
+ if (akp_size == \-1) {
+ fprintf(fp, "KEYCTL_READ failed: %s\en", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+\&
+ auth_key_payload[akp_size] = \[aq]\e0\[aq];
+ fprintf(fp, "Auth key payload: %s\en", auth_key_payload);
+\&
+ /*
+ * For interest, get the ID of the authorization key and
+ * display it.
+ */
+ auth_key = keyctl(KEYCTL_GET_KEYRING_ID,
+ KEY_SPEC_REQKEY_AUTH_KEY);
+ if (auth_key == \-1) {
+ fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\en",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+\&
+ fprintf(fp, "Auth key ID: %jx\en", (uintmax_t) auth_key);
+\&
+ /*
+ * Fetch key ID for the request_key(2) destination keyring.
+ */
+ dest_keyring = keyctl(KEYCTL_GET_KEYRING_ID,
+ KEY_SPEC_REQUESTOR_KEYRING);
+ if (dest_keyring == \-1) {
+ fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\en",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+\&
+ fprintf(fp, "Destination keyring: %jx\en", (uintmax_t) dest_keyring);
+\&
+ /*
+ * Fetch the description of the authorization key. This
+ * allows us to see the key type, UID, GID, permissions,
+ * and description (name) of the key. Among other things,
+ * we will see that the name of the key is a hexadecimal
+ * string representing the ID of the key to be instantiated.
+ */
+ if (keyctl(KEYCTL_DESCRIBE, KEY_SPEC_REQKEY_AUTH_KEY,
+ dbuf, sizeof(dbuf)) == \-1)
+ {
+ fprintf(fp, "KEYCTL_DESCRIBE failed: %s\en", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+\&
+ fprintf(fp, "Auth key description: %s\en", dbuf);
+\&
+ /*
+ * Instantiate the key using the callout data that was supplied
+ * in the payload of the authorization key.
+ */
+ if (keyctl(KEYCTL_INSTANTIATE, key_to_instantiate,
+ auth_key_payload, akp_size + 1, dest_keyring) == \-1)
+ {
+ fprintf(fp, "KEYCTL_INSTANTIATE failed: %s\en",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.ad l
+.nh
+.BR keyctl (1),
+.BR add_key (2),
+.BR request_key (2),
+.\" .BR find_key_by_type_and_name (3)
+.\" There is a man page, but this function seems not to exist
+.BR keyctl (3),
+.BR keyctl_assume_authority (3),
+.BR keyctl_chown (3),
+.BR keyctl_clear (3),
+.BR keyctl_describe (3),
+.BR keyctl_describe_alloc (3),
+.BR keyctl_dh_compute (3),
+.BR keyctl_dh_compute_alloc (3),
+.BR keyctl_get_keyring_ID (3),
+.BR keyctl_get_persistent (3),
+.BR keyctl_get_security (3),
+.BR keyctl_get_security_alloc (3),
+.BR keyctl_instantiate (3),
+.BR keyctl_instantiate_iov (3),
+.BR keyctl_invalidate (3),
+.BR keyctl_join_session_keyring (3),
+.BR keyctl_link (3),
+.BR keyctl_negate (3),
+.BR keyctl_read (3),
+.BR keyctl_read_alloc (3),
+.BR keyctl_reject (3),
+.BR keyctl_revoke (3),
+.BR keyctl_search (3),
+.BR keyctl_session_to_parent (3),
+.BR keyctl_set_reqkey_keyring (3),
+.BR keyctl_set_timeout (3),
+.BR keyctl_setperm (3),
+.BR keyctl_unlink (3),
+.BR keyctl_update (3),
+.BR recursive_key_scan (3),
+.BR recursive_session_key_scan (3),
+.BR capabilities (7),
+.BR credentials (7),
+.BR keyrings (7),
+.BR keyutils (7),
+.BR persistent\-keyring (7),
+.BR process\-keyring (7),
+.BR session\-keyring (7),
+.BR thread\-keyring (7),
+.BR user\-keyring (7),
+.BR user_namespaces (7),
+.BR user\-session\-keyring (7),
+.BR request\-key (8)
+.PP
+The kernel source files under
+.I Documentation/security/keys/
+(or, before Linux 4.13, in the file
+.IR Documentation/security/keys.txt ).