[automerger skipped] DO NOT MERGE - Skip pi-platform-release (PPRL.190505.001) in stage-aosp-master
am: 9017c9f0c5 -s ours
am skip reason: subject contains skip directive

Change-Id: I0ef0eebbb25a61634d13813e511edfb582cb74a9
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 0987139..69cbabb 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -704,10 +704,27 @@
 }
 
 bool KeyBlobEntry::hasKeyBlob() const {
-    return !access(getKeyBlobPath().c_str(), R_OK | W_OK);
+    int trys = 3;
+    while (trys--) {
+        if (!access(getKeyBlobPath().c_str(), R_OK | W_OK)) return true;
+        if (errno == ENOENT) return false;
+        LOG(WARNING) << "access encountered " << strerror(errno) << " (" << errno << ")"
+                     << " while checking for key blob";
+        if (errno != EAGAIN) break;
+    }
+    return false;
 }
+
 bool KeyBlobEntry::hasCharacteristicsBlob() const {
-    return !access(getCharacteristicsBlobPath().c_str(), R_OK | W_OK);
+    int trys = 3;
+    while (trys--) {
+        if (!access(getCharacteristicsBlobPath().c_str(), R_OK | W_OK)) return true;
+        if (errno == ENOENT) return false;
+        LOG(WARNING) << "access encountered " << strerror(errno) << " (" << errno << ")"
+                     << " while checking for key characteristics blob";
+        if (errno != EAGAIN) break;
+    }
+    return false;
 }
 
 static std::tuple<bool, uid_t, std::string> filename2UidAlias(const std::string& filepath) {
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 1319b23..5e7efab 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); }
@@ -374,17 +372,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,
@@ -996,9 +990,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:
@@ -1006,18 +999,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(
@@ -1031,15 +1021,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));
     }
 
@@ -1277,7 +1259,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;
     }
@@ -1295,7 +1278,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
diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp
index 1ce1210..25fa10b 100644
--- a/keystore/tests/Android.bp
+++ b/keystore/tests/Android.bp
@@ -37,3 +37,33 @@
      cfi: false,
    }
 }
+
+cc_test {
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+        "-O0",
+    ],
+    srcs: [
+        "confirmationui_invocation_test.cpp",
+        "gtest_main.cpp",
+    ],
+    name: "confirmationui_invocation_test",
+    static_libs: [
+        "android.hardware.confirmationui@1.0",
+        "libbase",
+        "libgtest_main",
+        "libutils",
+        "liblog",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libkeystore_aidl", // for IKeyStoreService.asInterface()
+        "libkeystore_binder",
+        "libkeystore_parcelables",
+    ],
+   sanitize: {
+     cfi: false,
+   }
+}
diff --git a/keystore/tests/confirmationui_invocation_test.cpp b/keystore/tests/confirmationui_invocation_test.cpp
new file mode 100644
index 0000000..f5182b5
--- /dev/null
+++ b/keystore/tests/confirmationui_invocation_test.cpp
@@ -0,0 +1,92 @@
+/*
+**
+** Copyright 2019, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <android/hardware/confirmationui/1.0/types.h>
+#include <android/security/BnConfirmationPromptCallback.h>
+#include <android/security/keystore/IKeystoreService.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <future>
+#include <tuple>
+#include <vector>
+
+using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
+using android::IBinder;
+using android::IServiceManager;
+using android::sp;
+using android::String16;
+using android::security::keystore::IKeystoreService;
+
+using namespace std::literals::chrono_literals;
+
+class ConfirmationListener
+    : public android::security::BnConfirmationPromptCallback,
+      public std::promise<std::tuple<ConfirmationResponseCode, std::vector<uint8_t>>> {
+  public:
+    ConfirmationListener() {}
+
+    virtual ::android::binder::Status
+    onConfirmationPromptCompleted(int32_t result,
+                                  const ::std::vector<uint8_t>& dataThatWasConfirmed) override {
+        this->set_value({static_cast<ConfirmationResponseCode>(result), dataThatWasConfirmed});
+        return ::android::binder::Status::ok();
+    }
+};
+
+TEST(ConfirmationInvocationTest, InvokeAndCancel) {
+    android::ProcessState::self()->startThreadPool();
+
+    sp<IServiceManager> sm = android::defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> service = android::interface_cast<IKeystoreService>(binder);
+    ASSERT_TRUE(service);
+
+    String16 promptText16("Just a little test!");
+    String16 locale16("en");
+    std::vector<uint8_t> extraData{0xaa, 0xff, 0x00, 0x55};
+
+    sp<ConfirmationListener> listener = new ConfirmationListener();
+
+    auto future = listener->get_future();
+    int32_t aidl_return;
+
+    android::binder::Status status = service->presentConfirmationPrompt(
+        listener, promptText16, extraData, locale16, 0, &aidl_return);
+    ASSERT_TRUE(status.isOk()) << "Presenting confirmation prompt failed with binder status '"
+                               << status.toString8().c_str() << "'.\n";
+    ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
+    ASSERT_EQ(responseCode, ConfirmationResponseCode::OK)
+        << "Presenting confirmation prompt failed with response code " << aidl_return << ".\n";
+
+    auto fstatus = future.wait_for(2s);
+    EXPECT_EQ(fstatus, std::future_status::timeout);
+
+    status = service->cancelConfirmationPrompt(listener, &aidl_return);
+    ASSERT_TRUE(status.isOk());
+
+    responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
+    ASSERT_EQ(responseCode, ConfirmationResponseCode::OK);
+
+    future.wait();
+    auto [rc, dataThatWasConfirmed] = future.get();
+
+    ASSERT_EQ(rc, ConfirmationResponseCode::Aborted);
+}