/* Do not cache key if it is a kernel thread */ if (!(t->flags & PF_KTHREAD)) {
key_put(t->cached_requested_key);
t->cached_requested_key = key_get(key);
set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
} #endif
}
/* attach the auth key to the session keyring */
ret = key_link(keyring, authkey); if (ret < 0) goto error_link;
/* record the UID and GID */
sprintf(uid_str, "%d", from_kuid(&init_user_ns, cred->fsuid));
sprintf(gid_str, "%d", from_kgid(&init_user_ns, cred->fsgid));
/* we say which key is under construction */
sprintf(key_str, "%d", key->serial);
/* we specify the process's default keyrings */
sprintf(keyring_str[0], "%d",
cred->thread_keyring ? cred->thread_keyring->serial : 0);
/* set up a minimal environment */
i = 0;
envp[i++] = "HOME=/";
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
envp[i] = NULL;
/* set up the argument list */
i = 0;
argv[i++] = (char *)request_key;
argv[i++] = (char *)rka->op;
argv[i++] = key_str;
argv[i++] = uid_str;
argv[i++] = gid_str;
argv[i++] = keyring_str[0];
argv[i++] = keyring_str[1];
argv[i++] = keyring_str[2];
argv[i] = NULL;
/* do it */
ret = call_usermodehelper_keys(request_key, argv, envp, keyring,
UMH_WAIT_PROC);
kdebug("usermode -> 0x%x", ret); if (ret >= 0) { /* ret is the exit/wait code */ if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
key_validate(key) < 0)
ret = -ENOKEY; else /* ignore any errors from userspace if the key was
* instantiated */
ret = 0;
}
/* allocate an authorisation key */
authkey = request_key_auth_new(key, "create", callout_info, callout_len,
dest_keyring); if (IS_ERR(authkey)) return PTR_ERR(authkey);
/* Make the call */
actor = call_sbin_request_key; if (key->type->request_key)
actor = key->type->request_key;
ret = actor(authkey, aux);
/* check that the actor called complete_request_key() prior to
* returning an error */
WARN_ON(ret < 0 &&
!test_bit(KEY_FLAG_INVALIDATED, &authkey->flags));
/* find the appropriate keyring */ if (dest_keyring) { /* the caller supplied one */
key_get(dest_keyring);
} else { bool do_perm_check = true;
/* use a default keyring; falling through the cases until we
* find one that we actually have */ 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:
BUG();
}
/* *RequireWritepermissiononthekeyring.Thisisessential *becausethedefaultkeyringmaybethesessionkeyring,and *joiningakeyringonlyrequiresSearchpermission. * *However,thischeckisskippedforthe"requestorkeyring"so *that/sbin/request-keycanitselfuserequest_key()toadd *keystotheoriginalrequestor'sdestinationkeyring.
*/ 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;
}
}
}
/* the key is now present - we tell the caller that we found it by
* returning -EINPROGRESS */
key_already_present:
key_put(key);
mutex_unlock(&key_construction_mutex);
key = key_ref_to_ptr(key_ref); if (dest_keyring) {
ret = __key_link_begin(dest_keyring, &key->index_key, &edit); if (ret < 0) goto link_alloc_failed_unlocked;
ret = __key_link_check_live_key(dest_keyring, key); if (ret == 0)
__key_link(dest_keyring, key, &edit);
__key_link_end(dest_keyring, &key->index_key, edit); if (ret < 0) goto link_check_failed;
}
mutex_unlock(&user->cons_lock);
*_key = key;
kleave(" = -EINPROGRESS [%d]", key_serial(key)); return -EINPROGRESS;
if (type->match_preparse) {
ret = type->match_preparse(&ctx.match_data); if (ret < 0) {
key = ERR_PTR(ret); goto error;
}
}
key = check_cached_key(&ctx); if (key) goto error_free;
/* search all the process keyrings for a key */
rcu_read_lock();
key_ref = search_process_keyrings_rcu(&ctx);
rcu_read_unlock();
if (!IS_ERR(key_ref)) { if (dest_keyring) {
ret = key_task_permission(key_ref, current_cred(),
KEY_NEED_LINK); if (ret < 0) {
key_ref_put(key_ref);
key = ERR_PTR(ret); goto error_free;
}
}
key = key_ref_to_ptr(key_ref); if (dest_keyring) {
ret = key_link(dest_keyring, key); if (ret < 0) {
key_put(key);
key = ERR_PTR(ret); goto error_free;
}
}
/* Only cache the key on immediate success */
cache_requested_key(key);
} elseif (PTR_ERR(key_ref) != -EAGAIN) {
key = ERR_CAST(key_ref);
} else { /* the search failed, but the keyrings were searchable, so we
* should consult userspace if we can */
key = ERR_PTR(-ENOKEY); if (!callout_info) goto error_free;
key = check_cached_key(&ctx); if (key) return key;
/* search all the process keyrings for a key */
key_ref = search_process_keyrings_rcu(&ctx); if (IS_ERR(key_ref)) {
key = ERR_CAST(key_ref); if (PTR_ERR(key_ref) == -EAGAIN)
key = ERR_PTR(-ENOKEY);
} else {
key = key_ref_to_ptr(key_ref);
cache_requested_key(key);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.