Fix permission check in reset_uid and clear_uid

System should be able to call these methods with any targetUid.

(cherry picked from commit 01771ae9db7338377317d82e9c7d8dfa2d4299a8)

Bug: 20752184
Change-Id: Ieaeb2fa44b979970640abbd91c1d8a84f7c62b1f
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index b89ac82..e8c48d1 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -2230,7 +2230,7 @@
 
     int32_t clear_uid(int64_t targetUid64) {
         uid_t targetUid = getEffectiveUid(targetUid64);
-        if (!checkBinderPermission(P_CLEAR_UID, targetUid)) {
+        if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
             return ::PERMISSION_DENIED;
         }
 
@@ -2250,7 +2250,7 @@
 
     int32_t reset_uid(int32_t targetUid) {
         targetUid = getEffectiveUid(targetUid);
-        if (!checkBinderPermission(P_RESET_UID, targetUid)) {
+        if (!checkBinderPermissionSelfOrSystem(P_RESET_UID, targetUid)) {
             return ::PERMISSION_DENIED;
         }
         // Flush the auth token table to prevent stale tokens from sticking
@@ -2767,6 +2767,20 @@
 
     /**
      * Check if the caller of the current binder method has the required
+     * permission and the target uid is the caller or the caller is system.
+     */
+    inline bool 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)) {
+            ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
+            return false;
+        }
+        return getEffectiveUid(targetUid) == callingUid || callingUid == AID_SYSTEM;
+    }
+
+    /**
+     * Check if the caller of the current binder method has the required
      * permission or the target of the operation is the caller's uid. This is
      * for operation where the permission is only for cross-uid activity and all
      * uids are allowed to act on their own (ie: clearing all entries for a