security/keys/persistent.c

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

File Facts

System
Linux kernel
Corpus path
security/keys/persistent.c
Extension
.c
Size
4441 bytes
Lines
168
Domain
Core OS
Bucket
Security And Isolation
Inferred role
Core OS: implementation source
Status
source 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

if (ret == 0) {
			key_set_timeout(persistent, persistent_keyring_expiry);
			ret = persistent->serial;
		}
	}

	key_ref_put(persistent_ref);
	return ret;
}

/*
 * Get the persistent keyring for a specific UID and link it to the nominated
 * keyring.
 */
long keyctl_get_persistent(uid_t _uid, key_serial_t destid)
{
	struct user_namespace *ns = current_user_ns();
	key_ref_t dest_ref;
	kuid_t uid;
	long ret;

	/* -1 indicates the current user */
	if (_uid == (uid_t)-1) {
		uid = current_uid();
	} else {
		uid = make_kuid(ns, _uid);
		if (!uid_valid(uid))
			return -EINVAL;

		/* You can only see your own persistent cache if you're not
		 * sufficiently privileged.
		 */
		if (!uid_eq(uid, current_uid()) &&
		    !uid_eq(uid, current_euid()) &&
		    !ns_capable(ns, CAP_SETUID))
			return -EPERM;
	}

	/* There must be a destination keyring */
	dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
	if (IS_ERR(dest_ref))
		return PTR_ERR(dest_ref);
	if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) {
		ret = -ENOTDIR;
		goto out_put_dest;
	}

	ret = key_get_persistent(ns, uid, dest_ref);

out_put_dest:
	key_ref_put(dest_ref);
	return ret;
}

Annotation

Implementation Notes