Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

add_key(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)add_key: x64 248 / i386 286 / arm64-generic 217 / arm32 309; request_key: x64 249 / i386 287 / arm64-generic 218 / arm32 310; keyctl: x64 250 / i386 288 / arm64-generic 219 / arm32 311
Since (kernel)2.6.10 for add_key / request_key / keyctl core operations (man VERSIONS); later keyctl operations have their own dates (table below)
Man pageman2/add_key.2, man2/request_key.2, man2/keyctl.2 (cached, 2021-08-27); overview in keyrings(7)
glibc wrapperNone – glibc does not wrap the keyring syscalls; wrappers live in libkeyutils (<keyutils.h>, link with -lkeyutils)
Aliases coveredrequest_key (SC-request_key), keyctl (SC-keyctl) – the keyring API trio shares this page
Ledger IDSC-add_key

Purpose

The kernel key retention service stores security tokens (kerberos tickets, encryption keys, module signatures) with per-user quotas and permission bits. The API is three syscalls: add_key() creates or updates a key and links it into a keyring; request_key() finds a key by type+description, optionally triggering a /sbin/request-key user-space upcall to construct it; keyctl() is the control multiplexer (read, revoke, link, search, instantiate, timeout, and more).

Synopsis

/* no glibc wrapper: use libkeyutils or syscall(2) */
long add_key(const char *type, const char *description,
             const void *payload, size_t plen, key_serial_t keyring);

key_serial_t request_key(const char *type, const char *description,
                         const char *callout_info, key_serial_t dest_keyring);

long keyctl(int operation, ...);

Arguments and behavior

add_key(): type is a registered key type – keyring (payload NULL), user (arbitrary blob up to 32,767 bytes, kernel memory), logon (since 3.3, never readable from user space, description needs a service: prefix) or big_key (since 3.13, up to 1 MiB, large payloads spliced to encrypted tmpfs). If a matching type+description key already exists in the destination keyring, the type may update it in place; otherwise the new key displaces the old link. description is limited to 4096 bytes, type to 32. Destination keyring is a serial number or a special ID: KEY_SPEC_THREAD_KEYRING (-1), KEY_SPEC_PROCESS_KEYRING (-2), KEY_SPEC_SESSION_KEYRING (-3), KEY_SPEC_USER_KEYRING (-4), KEY_SPEC_USER_SESSION_KEYRING (-5), KEY_SPEC_GROUP_KEYRING (-6, defunct), KEY_SPEC_REQKEY_AUTH_KEY (-7), KEY_SPEC_REQUESTOR_KEYRING (-8) (values from <linux/keyctl.h>). request_key() searches thread -> process -> session keyrings breadth-first (search permission required); a miss with non-NULL callout_info forks the /sbin/request-key helper with an authorization key of type .request_key_auth; a miss with NULL callout_info fails ENOKEY. keyctl() operations (numbered constants in <linux/keyctl.h>): 0 KEYCTL_GET_KEYRING_ID, 1 JOIN_SESSION_KEYRING, 2 UPDATE, 3 REVOKE, 4 CHOWN, 5 SETPERM, 6 DESCRIBE, 7 CLEAR, 8 LINK, 9 UNLINK, 10 SEARCH, 11 READ, 12 INSTANTIATE, 13 NEGATE (all 2.6.10), 14 SET_REQKEY_KEYRING (2.6.13), 15 SET_TIMEOUT, 16 ASSUME_AUTHORITY (2.6.16), 17 GET_SECURITY (2.6.26), 18 SESSION_TO_PARENT (2.6.32), 19 REJECT, 20 INSTANTIATE_IOV (2.6.39), 21 INVALIDATE (3.5), 22 GET_PERSISTENT (3.13), 23 DH_COMPUTE (4.7), 29 RESTRICT_KEYRING (4.12); 24-28 KEYCTL_PKEY_* (public-key ops), 30 MOVE, 31 CAPABILITIES, 32 WATCH_KEY exist in the installed header without a pinned kernel date in our sources.

Return value and errors

add_key() returns the new key’s serial; keyctl() returns an operation-dependent nonnegative value. Common errors: EACCES (keyring not writable / no search permission), EDQUOT (per-user key quota exceeded), EFAULT, EINVAL (type/description length; bad payload; unprefixed logon description), EKEYEXPIRED, EKEYREVOKED, ENOKEY (keyring or key missing), ENOMEM, EPERM (type or keyring description starting with a period – reserved).

Flags and constants

ConstantValueMeaning
KEY_SPEC_THREAD_KEYRING-1Caller’s thread keyring
KEY_SPEC_PROCESS_KEYRING-2Caller’s process keyring
KEY_SPEC_SESSION_KEYRING-3Caller’s session keyring
KEY_SPEC_USER_KEYRING-4UID keyring
KEY_SPEC_USER_SESSION_KEYRING-5UID session keyring
KEY_SPEC_GROUP_KEYRING-6GID keyring (legacy/defunct)
KEY_SPEC_REQKEY_AUTH_KEY-7Assumed request_key authorization key
KEY_SPEC_REQUESTOR_KEYRING-8request_key destination in upcalled helper

Security and notes

Key permissions are four 8-bit masks (only six bits used per mask) for the possessor, user, group and other categories, granting view, read, write, search, link and setattr; KEYCTL_SETPERM changes the mask, and without CAP_SYS_ADMIN a caller may change permissions only on keys it owns (fsuid match) – keyctl.2. Session keyrings are attached at login by pam_keyinit (request_key.2 comment). /proc/keys lists a user’s keys with state flags, permission mask, UID/GID, type and description; it also displays the expiry countdown set by KEYCTL_SET_TIMEOUT and shows invalidated keys with an i flag until garbage collection (keyctl.2). KEYCTL_DH_COMPUTE (4.7) implements Diffie-Hellman over user-type keys with optional KDF. Related process credentials: setuid-family pages.

References

  • Cached man pages: source-cache/man-pages-sparse/man2/add_key.2, request_key.2, keyctl.2
  • Online: https://man7.org/linux/man-pages/man2/add_key.2.html
  • Constants: /usr/include/linux/keyctl.h (KEY_SPEC_, KEYCTL_ values)
  • Kernel tables: source-cache/kernel/syscall_64.tbl (248, 249, 250)