return true;
}
- static std::string keyname(const std::string& raw_ref) {
+ static char const* const NAME_PREFIXES[] = {
+ "ext4",
+ "f2fs",
+ "fscrypt",
+ nullptr
+ };
+
+ static std::string keyname(const std::string& prefix, const std::string& raw_ref) {
std::ostringstream o;
- o << "ext4:";
+ o << prefix << ":";
- for (auto i : raw_ref) {
+ for (unsigned char i : raw_ref) {
o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
}
return o.str();
return true;
}
- auto ref = keyname(raw_ref);
+static bool evict_key(const std::string &raw_ref) {
- auto key_serial = keyctl_search(device_keyring, "logon", ref.c_str(), 0);
-
- // Unlink the key from the keyring. Prefer unlinking to revoking or
- // invalidating, since unlinking is actually no less secure currently, and
- // it avoids bugs in certain kernel versions where the keyring key is
- // referenced from places it shouldn't be.
- if (keyctl_unlink(key_serial, device_keyring) != 0) {
- PLOG(ERROR) << "Failed to unlink key with serial " << key_serial << " ref " << ref;
- return false;
+ key_serial_t device_keyring;
+ if (!e4crypt_keyring(&device_keyring)) return false;
- LOG(DEBUG) << "Unlinked key with serial " << key_serial << " ref " << ref;
- return true;
++ bool success = true;
++ for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
++ auto ref = keyname(*name_prefix, raw_ref);
++ auto key_serial = keyctl_search(device_keyring, "logon", ref.c_str(), 0);
++
++ // Unlink the key from the keyring. Prefer unlinking to revoking or
++ // invalidating, since unlinking is actually no less secure currently, and
++ // it avoids bugs in certain kernel versions where the keyring key is
++ // referenced from places it shouldn't be.
++ if (keyctl_unlink(key_serial, device_keyring) != 0) {
++ PLOG(ERROR) << "Failed to unlink key with serial " << key_serial << " ref " << ref;
++ success = false;
++ } else {
++ LOG(DEBUG) << "Unlinked key with serial " << key_serial << " ref " << ref;
++ }
+ }
++ return success;
+}
+
+static bool evict_ce_key(userid_t user_id) {
+ s_ce_keys.erase(user_id);
+ bool success = true;
+ std::string raw_ref;
+ // If we haven't loaded the CE key, no need to evict it.
+ if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) {
+ success &= evict_key(raw_ref);
+ }
+ s_ce_key_raw_refs.erase(user_id);
+ return success;
+}
+
bool e4crypt_destroy_user_key(userid_t user_id) {
LOG(DEBUG) << "e4crypt_destroy_user_key(" << user_id << ")";
if (!e4crypt_is_native()) {