[automerger skipped] Grant VTS tests all permissions in keystore on userdebug/eng am: cfe00de661 -s ours
am: 2c52bdb0c2 -s ours
am skip reason: change_id Ic6eb5748e0e19b64a44c4bdf88a7074f7367db3d with SHA1 84e7231d73 is in history
Change-Id: I3493d6a7344ca1dd7a56191e9d53a5537258beea
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 9bd363f..356ac1b 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -9,7 +9,16 @@
],
sanitize: {
- misc_undefined: ["integer"],
+ misc_undefined: [
+ "signed-integer-overflow",
+ "unsigned-integer-overflow",
+ "shift",
+ "integer-divide-by-zero",
+ "implicit-unsigned-integer-truncation",
+ // BUG: 123630767
+ //"implicit-signed-integer-truncation",
+ "implicit-integer-sign-change",
+ ],
},
clang: true,
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index f9485a4..9dd85d6 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -420,7 +420,16 @@
if (rawBlobIsEncrypted(*rawBlob)) {
rc = AES_gcm_decrypt(rawBlob->value /* in */, rawBlob->value /* out */, encryptedLength,
aes_key, rawBlob->initialization_vector, rawBlob->aead_tag);
- if (rc != ResponseCode::NO_ERROR) return rc;
+ if (rc != ResponseCode::NO_ERROR) {
+ // If the blob was superencrypted and decryption failed, it is
+ // almost certain that decryption is failing due to a user's
+ // changed master key.
+ if ((rawBlob->flags & KEYSTORE_FLAG_SUPER_ENCRYPTED) &&
+ (rc == ResponseCode::VALUE_CORRUPTED)) {
+ return ResponseCode::KEY_PERMANENTLY_INVALIDATED;
+ }
+ return rc;
+ }
}
} else if (rawBlob->version < 3) {
blobv2& v2blob = reinterpret_cast<blobv2&>(*rawBlob);
diff --git a/keystore/include/keystore/keystore.h b/keystore/include/keystore/keystore.h
index a1d4c81..3aed8c2 100644
--- a/keystore/include/keystore/keystore.h
+++ b/keystore/include/keystore/keystore.h
@@ -44,6 +44,7 @@
SIGNATURE_INVALID = 14,
OP_AUTH_NEEDED = 15, // Auth is needed for this operation before it can be used.
KEY_ALREADY_EXISTS = 16,
+ KEY_PERMANENTLY_INVALIDATED = 17,
};
/*
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index a7fcd38..bbf93ad 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -69,8 +69,6 @@
constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
const char* kTimestampFilePath = "timestamp";
-const int ID_ATTESTATION_REQUEST_GENERIC_INFO = 1 << 0;
-const int ID_ATTESTATION_REQUEST_UNIQUE_DEVICE_ID = 1 << 1;
struct BIGNUM_Delete {
void operator()(BIGNUM* p) const { BN_free(p); }
@@ -364,17 +362,13 @@
return Status::ok();
}
- const String8 password8(password);
- // Flush the auth token table to prevent stale tokens from sticking
- // around.
- mKeyStore->getAuthTokenTable().Clear();
-
if (password.size() == 0) {
ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId);
mKeyStore->resetUser(userId, true);
*aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
return Status::ok();
} else {
+ const String8 password8(password);
switch (mKeyStore->getState(userId)) {
case ::STATE_UNINITIALIZED: {
// generate master key, encrypt with password, write to file,
@@ -966,9 +960,8 @@
return Status::ok();
}
-int isDeviceIdAttestationRequested(const KeymasterArguments& params) {
+bool isDeviceIdAttestationRequested(const KeymasterArguments& params) {
const hardware::hidl_vec<KeyParameter>& paramsVec = params.getParameters();
- int result = 0;
for (size_t i = 0; i < paramsVec.size(); ++i) {
switch (paramsVec[i].tag) {
case Tag::ATTESTATION_ID_BRAND:
@@ -976,18 +969,15 @@
case Tag::ATTESTATION_ID_MANUFACTURER:
case Tag::ATTESTATION_ID_MODEL:
case Tag::ATTESTATION_ID_PRODUCT:
- result |= ID_ATTESTATION_REQUEST_GENERIC_INFO;
- break;
case Tag::ATTESTATION_ID_IMEI:
case Tag::ATTESTATION_ID_MEID:
case Tag::ATTESTATION_ID_SERIAL:
- result |= ID_ATTESTATION_REQUEST_UNIQUE_DEVICE_ID;
- break;
+ return true;
default:
continue;
}
}
- return result;
+ return false;
}
Status KeyStoreService::attestKey(
@@ -1000,15 +990,7 @@
uid_t callingUid = IPCThreadState::self()->getCallingUid();
- int needsIdAttestation = isDeviceIdAttestationRequested(params);
- bool needsUniqueIdAttestation = needsIdAttestation & ID_ATTESTATION_REQUEST_UNIQUE_DEVICE_ID;
- bool isPrimaryUserSystemUid = (callingUid == AID_SYSTEM);
- bool isSomeUserSystemUid = (get_app_id(callingUid) == AID_SYSTEM);
- // Allow system context from any user to request attestation with basic device information,
- // while only allow system context from user 0 (device owner) to request attestation with
- // unique device ID.
- if ((needsIdAttestation && !isSomeUserSystemUid) ||
- (needsUniqueIdAttestation && !isPrimaryUserSystemUid)) {
+ if (isDeviceIdAttestationRequested(params) && (get_app_id(callingUid) != AID_SYSTEM)) {
return AIDL_RETURN(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
}
@@ -1236,7 +1218,8 @@
bool KeyStoreService::checkBinderPermission(perm_t permission, int32_t targetUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
pid_t spid = IPCThreadState::self()->getCallingPid();
- if (!has_permission(callingUid, permission, spid)) {
+ const char* ssid = IPCThreadState::self()->getCallingSid();
+ if (!has_permission(callingUid, permission, spid, ssid)) {
ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
return false;
}
@@ -1254,7 +1237,8 @@
bool KeyStoreService::checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
pid_t spid = IPCThreadState::self()->getCallingPid();
- if (!has_permission(callingUid, permission, spid)) {
+ const char* ssid = IPCThreadState::self()->getCallingSid();
+ if (!has_permission(callingUid, permission, spid, ssid)) {
ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
return false;
}
diff --git a/keystore/keystore_client.proto b/keystore/keystore_client.proto
index cd520dc..cbafd54 100644
--- a/keystore/keystore_client.proto
+++ b/keystore/keystore_client.proto
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+syntax = "proto2";
+
package keystore;
option optimize_for = LITE_RUNTIME;
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index 70f38cc..f3eadd7 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -156,6 +156,7 @@
keyStore->initialize();
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(keyStore);
+ service->setRequestingSid(true);
android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
CHECK(ret == android::OK) << "Couldn't register binder service!";
diff --git a/keystore/permissions.cpp b/keystore/permissions.cpp
index a172761..05454cb 100644
--- a/keystore/permissions.cpp
+++ b/keystore/permissions.cpp
@@ -92,6 +92,7 @@
struct audit_data {
pid_t pid;
uid_t uid;
+ const char* sid;
};
const char* get_perm_label(perm_t perm) {
@@ -111,7 +112,8 @@
return 0;
}
- snprintf(buf, len, "pid=%d uid=%d", ad->pid, ad->uid);
+ const char* sid = ad->sid ? ad->sid : "N/A";
+ snprintf(buf, len, "pid=%d uid=%d sid=%s", ad->pid, ad->uid, sid);
return 0;
}
@@ -131,7 +133,7 @@
return 0;
}
-static bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid) {
+static bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid, const char* ssid) {
audit_data ad;
char* sctx = nullptr;
const char* selinux_class = "keystore_key";
@@ -141,15 +143,18 @@
return false;
}
- if (getpidcon(spid, &sctx) != 0) {
+ if (ssid == nullptr && getpidcon(spid, &sctx) != 0) {
ALOGE("SELinux: Failed to get source pid context.\n");
return false;
}
+ const char* use_sid = ssid ? ssid : sctx;
+
ad.pid = spid;
ad.uid = uid;
+ ad.sid = use_sid;
- bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm,
+ bool allowed = selinux_check_access(use_sid, tctx, selinux_class, str_perm,
reinterpret_cast<void*>(&ad)) == 0;
freecon(sctx);
return allowed;
@@ -171,20 +176,24 @@
return uid;
}
-bool has_permission(uid_t uid, perm_t perm, pid_t spid) {
+bool has_permission(uid_t uid, perm_t perm, pid_t spid, const char* sid) {
// All system users are equivalent for multi-user support.
if (get_app_id(uid) == AID_SYSTEM) {
uid = AID_SYSTEM;
}
+ if (sid == nullptr) {
+ android_errorWriteLog(0x534e4554, "121035042");
+ }
+
for (size_t i = 0; i < sizeof(user_perms) / sizeof(user_perms[0]); i++) {
struct user_perm user = user_perms[i];
if (user.uid == uid) {
- return (user.perms & perm) && keystore_selinux_check_access(uid, perm, spid);
+ return (user.perms & perm) && keystore_selinux_check_access(uid, perm, spid, sid);
}
}
- return (DEFAULT_PERMS & perm) && keystore_selinux_check_access(uid, perm, spid);
+ return (DEFAULT_PERMS & perm) && keystore_selinux_check_access(uid, perm, spid, sid);
}
/**
diff --git a/keystore/permissions.h b/keystore/permissions.h
index 1f7b7a6..1dd0089 100644
--- a/keystore/permissions.h
+++ b/keystore/permissions.h
@@ -51,7 +51,12 @@
*/
uid_t get_keystore_euid(uid_t uid);
-bool has_permission(uid_t uid, perm_t perm, pid_t spid);
+/**
+ * Returns true if the uid/pid/sid has a permission. Checks based on sid if available.
+ *
+ * sid may be null on older kernels
+ */
+bool has_permission(uid_t uid, perm_t perm, pid_t spid, const char* sid);
/**
* Returns true if the callingUid is allowed to interact in the targetUid's