Merge "keystore: use getCallingSid"
This commit is contained in:
commit
8a74b61ad6
4 changed files with 27 additions and 10 deletions
|
@ -1222,7 +1222,8 @@ uid_t KeyStoreService::getEffectiveUid(int32_t targetUid) {
|
|||
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;
|
||||
}
|
||||
|
@ -1240,7 +1241,8 @@ bool KeyStoreService::checkBinderPermission(perm_t permission, int32_t targetUid
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -156,6 +156,7 @@ int main(int argc, char* argv[]) {
|
|||
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!";
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ static const perm_t DEFAULT_PERMS = static_cast<perm_t>(
|
|||
struct audit_data {
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
const char* sid;
|
||||
};
|
||||
|
||||
const char* get_perm_label(perm_t perm) {
|
||||
|
@ -97,7 +98,8 @@ static int audit_callback(void* data, security_class_t /* cls */, char* buf, siz
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -117,7 +119,7 @@ int configure_selinux() {
|
|||
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";
|
||||
|
@ -127,15 +129,18 @@ static bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid) {
|
|||
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;
|
||||
|
@ -157,20 +162,24 @@ uid_t get_keystore_euid(uid_t uid) {
|
|||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,7 +51,12 @@ const char* get_perm_label(perm_t perm);
|
|||
*/
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue