Merge "keystore: allow system UID to WiFi or VPN"
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 1ddf4ee..09bcf33 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -171,6 +171,11 @@
return DEFAULT_PERMS & perm;
}
+/**
+ * Returns the UID that the callingUid should act as. This is here for
+ * legacy support of the WiFi and VPN systems and should be removed
+ * when WiFi can operate in its own namespace.
+ */
static uid_t get_keystore_euid(uid_t uid) {
for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
struct user_euid user = user_euids[i];
@@ -182,6 +187,21 @@
return uid;
}
+/**
+ * Returns true if the callingUid is allowed to interact in the targetUid's
+ * namespace.
+ */
+static bool is_granted_to(uid_t callingUid, uid_t targetUid) {
+ for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
+ struct user_euid user = user_euids[i];
+ if (user.euid == callingUid && user.uid == targetUid) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Here is the encoding of keys. This is necessary in order to allow arbitrary
* characters in keys. Characters in [0-~] are not encoded. Others are encoded
* into two bytes. The first byte is one of [+-.] which represents the first
@@ -901,10 +921,10 @@
return responseCode;
}
- // If this is the Wifi or VPN user, they actually want system
- // UID keys.
- if (uid == AID_WIFI || uid == AID_VPN) {
- encode_key_for_uid(filename, AID_SYSTEM, keyName);
+ // If this is one of the legacy UID->UID mappings, use it.
+ uid_t euid = get_keystore_euid(uid);
+ if (euid != uid) {
+ encode_key_for_uid(filename, euid, keyName);
responseCode = keyStore->get(filename, keyBlob, type);
if (responseCode == NO_ERROR) {
return responseCode;
@@ -949,7 +969,6 @@
ALOGW("permission denied for %d: get", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
State state = mKeyStore->getState();
if (!isKeystoreUnlocked(state)) {
@@ -959,11 +978,10 @@
String8 name8(name);
char filename[NAME_MAX];
-
- encode_key_for_uid(filename, callingUid, name8);
-
Blob keyBlob;
- ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC);
+
+ ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
+ TYPE_GENERIC);
if (responseCode != ::NO_ERROR) {
ALOGW("Could not read %s", filename);
*item = NULL;
@@ -978,15 +996,16 @@
return ::NO_ERROR;
}
- int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid) {
+ int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!has_permission(callingUid, P_INSERT)) {
ALOGW("permission denied for %d: insert", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
- if (uid != -1) {
+ if (targetUid == -1) {
+ targetUid = callingUid;
+ } else if (!is_granted_to(callingUid, targetUid)) {
return ::PERMISSION_DENIED;
}
@@ -999,28 +1018,29 @@
String8 name8(name);
char filename[NAME_MAX];
- encode_key_for_uid(filename, callingUid, name8);
+ encode_key_for_uid(filename, targetUid, name8);
Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
return mKeyStore->put(filename, &keyBlob);
}
- int32_t del(const String16& name, int uid) {
+ int32_t del(const String16& name, int targetUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!has_permission(callingUid, P_DELETE)) {
ALOGW("permission denied for %d: del", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
- if (uid != -1) {
+ if (targetUid == -1) {
+ targetUid = callingUid;
+ } else if (!is_granted_to(callingUid, targetUid)) {
return ::PERMISSION_DENIED;
}
String8 name8(name);
char filename[NAME_MAX];
- encode_key_for_uid(filename, callingUid, name8);
+ encode_key_for_uid(filename, targetUid, name8);
Blob keyBlob;
ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC);
@@ -1030,22 +1050,23 @@
return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
}
- int32_t exist(const String16& name, int uid) {
+ int32_t exist(const String16& name, int targetUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!has_permission(callingUid, P_EXIST)) {
ALOGW("permission denied for %d: exist", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
- if (uid != -1) {
+ if (targetUid == -1) {
+ targetUid = callingUid;
+ } else if (!is_granted_to(callingUid, targetUid)) {
return ::PERMISSION_DENIED;
}
String8 name8(name);
char filename[NAME_MAX];
- encode_key_for_uid(filename, callingUid, name8);
+ encode_key_for_uid(filename, targetUid, name8);
if (access(filename, R_OK) == -1) {
return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
@@ -1053,15 +1074,16 @@
return ::NO_ERROR;
}
- int32_t saw(const String16& prefix, int uid, Vector<String16>* matches) {
+ int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!has_permission(callingUid, P_SAW)) {
ALOGW("permission denied for %d: saw", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
- if (uid != -1) {
+ if (targetUid == -1) {
+ targetUid = callingUid;
+ } else if (!is_granted_to(callingUid, targetUid)) {
return ::PERMISSION_DENIED;
}
@@ -1073,7 +1095,7 @@
const String8 prefix8(prefix);
char filename[NAME_MAX];
- int n = encode_key_for_uid(filename, callingUid, prefix8);
+ int n = encode_key_for_uid(filename, targetUid, prefix8);
struct dirent* file;
while ((file = readdir(dir)) != NULL) {
@@ -1202,15 +1224,16 @@
return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR;
}
- int32_t generate(const String16& name, int uid) {
+ int32_t generate(const String16& name, int targetUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!has_permission(callingUid, P_INSERT)) {
ALOGW("permission denied for %d: generate", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
- if (uid != -1) {
+ if (targetUid == -1) {
+ targetUid = callingUid;
+ } else if (!is_granted_to(callingUid, targetUid)) {
return ::PERMISSION_DENIED;
}
@@ -1245,7 +1268,7 @@
return ::SYSTEM_ERROR;
}
- encode_key_for_uid(filename, callingUid, name8);
+ encode_key_for_uid(filename, targetUid, name8);
Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
free(data);
@@ -1253,15 +1276,16 @@
return mKeyStore->put(filename, &keyBlob);
}
- int32_t import(const String16& name, const uint8_t* data, size_t length, int uid) {
+ int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!has_permission(callingUid, P_INSERT)) {
ALOGW("permission denied for %d: import", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
- if (uid != -1) {
+ if (targetUid == -1) {
+ targetUid = callingUid;
+ } else if (!is_granted_to(callingUid, targetUid)) {
return ::PERMISSION_DENIED;
}
@@ -1274,7 +1298,7 @@
String8 name8(name);
char filename[NAME_MAX];
- encode_key_for_uid(filename, callingUid, name8);
+ encode_key_for_uid(filename, targetUid, name8);
return mKeyStore->importKey(data, length, filename);
}
@@ -1286,7 +1310,6 @@
ALOGW("permission denied for %d: saw", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
State state = mKeyStore->getState();
if (!isKeystoreUnlocked(state)) {
@@ -1338,7 +1361,6 @@
ALOGW("permission denied for %d: verify", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
State state = mKeyStore->getState();
if (!isKeystoreUnlocked(state)) {
@@ -1350,7 +1372,8 @@
String8 name8(name);
int rc;
- ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, TYPE_KEY_PAIR);
+ ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
+ TYPE_KEY_PAIR);
if (responseCode != ::NO_ERROR) {
return responseCode;
}
@@ -1394,7 +1417,6 @@
ALOGW("permission denied for %d: get_pubkey", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
State state = mKeyStore->getState();
if (!isKeystoreUnlocked(state)) {
@@ -1432,22 +1454,23 @@
return ::NO_ERROR;
}
- int32_t del_key(const String16& name, int uid) {
+ int32_t del_key(const String16& name, int targetUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!has_permission(callingUid, P_DELETE)) {
ALOGW("permission denied for %d: del_key", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
- if (uid != -1) {
+ if (targetUid == -1) {
+ targetUid = callingUid;
+ } else if (!is_granted_to(callingUid, targetUid)) {
return ::PERMISSION_DENIED;
}
String8 name8(name);
char filename[NAME_MAX];
- encode_key_for_uid(filename, callingUid, name8);
+ encode_key_for_uid(filename, targetUid, name8);
Blob keyBlob;
ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR);
@@ -1482,7 +1505,6 @@
ALOGW("permission denied for %d: grant", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
State state = mKeyStore->getState();
if (!isKeystoreUnlocked(state)) {
@@ -1509,7 +1531,6 @@
ALOGW("permission denied for %d: ungrant", callingUid);
return ::PERMISSION_DENIED;
}
- callingUid = get_keystore_euid(callingUid);
State state = mKeyStore->getState();
if (!isKeystoreUnlocked(state)) {
@@ -1535,7 +1556,6 @@
ALOGW("permission denied for %d: getmtime", callingUid);
return -1L;
}
- callingUid = get_keystore_euid(callingUid);
String8 name8(name);
char filename[NAME_MAX];