diff options
author | Chad Brubaker <cbrubaker@google.com> | 2015-10-12 16:21:16 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-10-12 16:21:16 +0000 |
commit | bc22f8d63e2ca24ee4ee9d61258d6704bc78724b (patch) | |
tree | c7e0f9b063b9a81e7cdbe9fcf0f10e7adfe20046 | |
parent | 358bd1156745a470f87dacfd509d2876e7ef6327 (diff) | |
parent | 410ba59a76a8feb48ffb5bde3045ac6f76db0c36 (diff) | |
download | android_system_security-bc22f8d63e2ca24ee4ee9d61258d6704bc78724b.tar.gz android_system_security-bc22f8d63e2ca24ee4ee9d61258d6704bc78724b.tar.bz2 android_system_security-bc22f8d63e2ca24ee4ee9d61258d6704bc78724b.zip |
am 410ba59a: Fix failure to save master key on new profile
* commit '410ba59a76a8feb48ffb5bde3045ac6f76db0c36':
Fix failure to save master key on new profile
-rw-r--r-- | keystore/keystore.cpp | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp index 0906abf..bb5a411 100644 --- a/keystore/keystore.cpp +++ b/keystore/keystore.cpp @@ -920,6 +920,38 @@ public: } memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES); setupMasterKeys(); + return copyMasterKeyFile(src); + } + + ResponseCode copyMasterKeyFile(UserState* src) { + /* Copy the master key file to the new user. + * Unfortunately we don't have the src user's password so we cannot + * generate a new file with a new salt. + */ + int in = TEMP_FAILURE_RETRY(open(src->getMasterKeyFileName(), O_RDONLY)); + if (in < 0) { + return ::SYSTEM_ERROR; + } + blob rawBlob; + size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); + if (close(in) != 0) { + return ::SYSTEM_ERROR; + } + int out = TEMP_FAILURE_RETRY(open(mMasterKeyFile, + O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); + if (out < 0) { + return ::SYSTEM_ERROR; + } + size_t outLength = writeFully(out, (uint8_t*) &rawBlob, length); + if (close(out) != 0) { + return ::SYSTEM_ERROR; + } + if (outLength != length) { + ALOGW("blob not fully written %zu != %zu", outLength, length); + unlink(mMasterKeyFile); + return ::SYSTEM_ERROR; + } + return ::NO_ERROR; } @@ -1980,10 +2012,12 @@ public: } // Unconditionally clear the keystore, just to be safe. mKeyStore->resetUser(userId, false); - - // If the user has a parent user then use the parent's - // masterkey/password, otherwise there's nothing to do. if (parentId != -1) { + // This profile must share the same master key password as the parent + // profile. Because the password of the parent profile is not known + // here, the best we can do is copy the parent's master key and master + // key file. This makes this profile use the same master key as the + // parent profile, forever. return mKeyStore->copyMasterKey(parentId, userId); } else { return ::NO_ERROR; @@ -2021,7 +2055,17 @@ public: State state = mKeyStore->getState(userId); if (state != ::STATE_LOCKED) { - ALOGI("calling unlock when not locked, ignoring."); + switch (state) { + case ::STATE_NO_ERROR: + ALOGI("calling unlock when already unlocked, ignoring."); + break; + case ::STATE_UNINITIALIZED: + ALOGE("unlock called on uninitialized keystore."); + break; + default: + ALOGE("unlock called on keystore in unknown state: %d", state); + break; + } return state; } |