security/keys/request_key.c

Source file repositories/reference/linux-study-clean/security/keys/request_key.c

File Facts

System
Linux kernel
Corpus path
security/keys/request_key.c
Extension
.c
Size
22437 bytes
Lines
822
Domain
Core OS
Bucket
Security And Isolation
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (cred->jit_keyring) {
		case KEY_REQKEY_DEFL_DEFAULT:
		case KEY_REQKEY_DEFL_REQUESTOR_KEYRING:
			if (cred->request_key_auth) {
				authkey = cred->request_key_auth;
				down_read(&authkey->sem);
				rka = get_request_key_auth(authkey);
				if (!test_bit(KEY_FLAG_REVOKED,
					      &authkey->flags))
					dest_keyring =
						key_get(rka->dest_keyring);
				up_read(&authkey->sem);
				if (dest_keyring) {
					do_perm_check = false;
					break;
				}
			}

			fallthrough;
		case KEY_REQKEY_DEFL_THREAD_KEYRING:
			dest_keyring = key_get(cred->thread_keyring);
			if (dest_keyring)
				break;

			fallthrough;
		case KEY_REQKEY_DEFL_PROCESS_KEYRING:
			dest_keyring = key_get(cred->process_keyring);
			if (dest_keyring)
				break;

			fallthrough;
		case KEY_REQKEY_DEFL_SESSION_KEYRING:
			dest_keyring = key_get(cred->session_keyring);

			if (dest_keyring)
				break;

			fallthrough;
		case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
			ret = look_up_user_keyrings(NULL, &dest_keyring);
			if (ret < 0)
				return ret;
			break;

		case KEY_REQKEY_DEFL_USER_KEYRING:
			ret = look_up_user_keyrings(&dest_keyring, NULL);
			if (ret < 0)
				return ret;
			break;

		case KEY_REQKEY_DEFL_GROUP_KEYRING:
		default:
			return -EINVAL;
		}

		/*
		 * Require Write permission on the keyring.  This is essential
		 * because the default keyring may be the session keyring, and
		 * joining a keyring only requires Search permission.
		 *
		 * However, this check is skipped for the "requestor keyring" so
		 * that /sbin/request-key can itself use request_key() to add
		 * keys to the original requestor's destination keyring.
		 */
		if (dest_keyring && do_perm_check) {
			ret = key_permission(make_key_ref(dest_keyring, 1),
					     KEY_NEED_WRITE);
			if (ret) {
				key_put(dest_keyring);
				return ret;
			}
		}
	}

	*_dest_keyring = dest_keyring;
	kleave(" [dk %d]", key_serial(dest_keyring));
	return 0;
}

/*
 * Allocate a new key in under-construction state and attempt to link it in to
 * the requested keyring.
 *
 * May return a key that's already under construction instead if there was a
 * race between two thread calling request_key().
 */
static int construct_alloc_key(struct keyring_search_context *ctx,
			       struct key *dest_keyring,
			       unsigned long flags,
			       struct key_user *user,

Annotation

Implementation Notes