^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* General persistent per-UID keyrings register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/user_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/cred.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) unsigned persistent_keyring_expiry = 3 * 24 * 3600; /* Expire after 3 days of non-use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Create the persistent keyring register for the current user namespace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Called with the namespace's sem locked for writing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int key_create_persistent_register(struct user_namespace *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct key *reg = keyring_alloc(".persistent_register",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) KUIDT_INIT(0), KGIDT_INIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) current_cred(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) KEY_USR_VIEW | KEY_USR_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (IS_ERR(reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return PTR_ERR(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) ns->persistent_keyring_register = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Create the persistent keyring for the specified user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Called with the namespace's sem locked for writing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct keyring_index_key *index_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct key *persistent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) key_ref_t reg_ref, persistent_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (!ns->persistent_keyring_register) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) long err = key_create_persistent_register(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) reg_ref = make_key_ref(ns->persistent_keyring_register, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) persistent_ref = find_key_to_update(reg_ref, index_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (persistent_ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return persistent_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) persistent = keyring_alloc(index_key->description,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) uid, INVALID_GID, current_cred(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) KEY_USR_VIEW | KEY_USR_READ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) KEY_ALLOC_NOT_IN_QUOTA, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ns->persistent_keyring_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (IS_ERR(persistent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return ERR_CAST(persistent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return make_key_ref(persistent, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Get the persistent keyring for a specific UID and link it to the nominated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * keyring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static long key_get_persistent(struct user_namespace *ns, kuid_t uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) key_ref_t dest_ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct keyring_index_key index_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct key *persistent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) key_ref_t reg_ref, persistent_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) char buf[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Look in the register if it exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) memset(&index_key, 0, sizeof(index_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) index_key.type = &key_type_keyring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) index_key.description = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) index_key.desc_len = sprintf(buf, "_persistent.%u", from_kuid(ns, uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) key_set_index_key(&index_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (ns->persistent_keyring_register) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) reg_ref = make_key_ref(ns->persistent_keyring_register, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) down_read(&ns->keyring_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) persistent_ref = find_key_to_update(reg_ref, &index_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) up_read(&ns->keyring_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (persistent_ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* It wasn't in the register, so we'll need to create it. We might
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * also need to create the register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) down_write(&ns->keyring_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) persistent_ref = key_create_persistent(ns, uid, &index_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) up_write(&ns->keyring_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!IS_ERR(persistent_ref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return PTR_ERR(persistent_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = key_task_permission(persistent_ref, current_cred(), KEY_NEED_LINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) persistent = key_ref_to_ptr(persistent_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ret = key_link(key_ref_to_ptr(dest_ref), persistent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) key_set_timeout(persistent, persistent_keyring_expiry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = persistent->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) key_ref_put(persistent_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Get the persistent keyring for a specific UID and link it to the nominated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * keyring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) long keyctl_get_persistent(uid_t _uid, key_serial_t destid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct user_namespace *ns = current_user_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) key_ref_t dest_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* -1 indicates the current user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (_uid == (uid_t)-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) uid = current_uid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) uid = make_kuid(ns, _uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!uid_valid(uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* You can only see your own persistent cache if you're not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * sufficiently privileged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!uid_eq(uid, current_uid()) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) !uid_eq(uid, current_euid()) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) !ns_capable(ns, CAP_SETUID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* There must be a destination keyring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (IS_ERR(dest_ref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return PTR_ERR(dest_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ret = -ENOTDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) goto out_put_dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ret = key_get_persistent(ns, uid, dest_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) out_put_dest:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) key_ref_put(dest_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }