From e752a5cc64b78f799525aa4e44e5f74e8c402465 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Mon, 15 Jan 2018 17:14:20 -0800 Subject: No sensor access to idle UIDs - native framework Idle UIDs are ones that were in the background for long enough time. Currently such apps can access sensor data even though they have no user perceptible components running. This affects the user's privacy since an app in the background can use sensor data to infer location, activity, habits, etc. The goal is to restrict sensor access for all apps in the ecosystem regardless of target SDK which means the solution should be backwards compatible. At the high level the sesnor service observes UID state changes and applies policy like this: Continuous sensors: for sensros in this reporting mode when the UID goes in the background we will stop dispatching events. Once the UID goes active we will start reporting the events. While this is an app visible behavior change we would rather do that vs delivering fake events. Flush events: there is no change in behavior based on the UID state. Hence, idle apps can request a flush and would get the completion callback. From an app perspective flushing works at any point. Trigger events: for sensors in this reporting mode when the UID goes in the background we will not report any trigger events. From an app perspective the sensor just did not pick up any events. On-change events: for sensors in this reporting mode when the UID goes in the background we will not report any change events. From an app perspective the sensor just did not pick up any events. Wake locks: since UIDs in idle state cannot acquire wakelocks we will not be grabbing a wakelock on behalf of apps in that state. Test: Added - SensorTest#testSanitizedContinuousEventsUidIdle Added - SensorTest#testBatchAndFlushUidIdle Pass - cts-tradefed run cts-dev -m CtsSensorTestCases bug:63938985 Change-Id: I156803610ad6d86afaae641ebbb0e84f16d2344b --- libs/binder/IPermissionController.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'libs/binder/IPermissionController.cpp') diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp index 674bddf218..ef67ab8dd2 100644 --- a/libs/binder/IPermissionController.cpp +++ b/libs/binder/IPermissionController.cpp @@ -78,6 +78,18 @@ public: if (reply.readExceptionCode() != 0) return false; return reply.readInt32() != 0; } + + virtual int getPackageUid(const String16& package, int flags) + { + Parcel data, reply; + data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor()); + data.writeString16(package); + data.writeInt32(flags); + remote()->transact(GET_PACKAGE_UID_TRANSACTION, data, &reply); + // fail on exception + if (reply.readExceptionCode() != 0) return false; + return reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController"); @@ -122,6 +134,16 @@ status_t BnPermissionController::onTransact( return NO_ERROR; } break; + case GET_PACKAGE_UID_TRANSACTION: { + CHECK_INTERFACE(IPermissionController, data, reply); + String16 package = data.readString16(); + int flags = data.readInt32(); + const int uid = getPackageUid(package, flags); + reply->writeNoException(); + reply->writeInt32(uid); + return NO_ERROR; + } break; + default: return BBinder::onTransact(code, data, reply, flags); } -- cgit v1.2.3-59-g8ed1b From 7afcb3f98e7342985ba5e62bf6d3a5ac1282e545 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 9 Apr 2018 12:58:40 -0600 Subject: Protect usage data with OP_GET_USAGE_STATS. APIs that return package usage data (such as the new StatsManager) must ensure that callers hold both the PACKAGE_USAGE_STATS permission and the OP_GET_USAGE_STATS app-op. Add noteOp() method that can be called from native code. Also add missing security checks on shell commands. Bug: 77662908 Test: builds, boots Change-Id: I15efd6f5dde61e807269b5132a052548ea4e800f --- libs/binder/IPermissionController.cpp | 24 ++++++++++++++++++++++ libs/binder/PermissionController.cpp | 6 ++++++ libs/binder/include/binder/IPermissionController.h | 9 +++++--- libs/binder/include/binder/PermissionController.h | 8 ++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) (limited to 'libs/binder/IPermissionController.cpp') diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp index ef67ab8dd2..89ebc6c1aa 100644 --- a/libs/binder/IPermissionController.cpp +++ b/libs/binder/IPermissionController.cpp @@ -49,6 +49,19 @@ public: return reply.readInt32() != 0; } + virtual int32_t noteOp(const String16& op, int32_t uid, const String16& packageName) + { + Parcel data, reply; + data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor()); + data.writeString16(op); + data.writeInt32(uid); + data.writeString16(packageName); + remote()->transact(NOTE_OP_TRANSACTION, data, &reply); + // fail on exception + if (reply.readExceptionCode() != 0) return 2; // MODE_ERRORED + return reply.readInt32(); + } + virtual void getPackagesForUid(const uid_t uid, Vector& packages) { Parcel data, reply; @@ -111,6 +124,17 @@ status_t BnPermissionController::onTransact( return NO_ERROR; } break; + case NOTE_OP_TRANSACTION: { + CHECK_INTERFACE(IPermissionController, data, reply); + String16 op = data.readString16(); + int32_t uid = data.readInt32(); + String16 packageName = data.readString16(); + int32_t res = noteOp(op, uid, packageName); + reply->writeNoException(); + reply->writeInt32(res); + return NO_ERROR; + } break; + case GET_PACKAGES_FOR_UID_TRANSACTION: { CHECK_INTERFACE(IPermissionController, data, reply); int32_t uid = data.readInt32(); diff --git a/libs/binder/PermissionController.cpp b/libs/binder/PermissionController.cpp index 25748cadbb..96df33c9cf 100644 --- a/libs/binder/PermissionController.cpp +++ b/libs/binder/PermissionController.cpp @@ -59,6 +59,12 @@ bool PermissionController::checkPermission(const String16& permission, int32_t p return service != NULL ? service->checkPermission(permission, pid, uid) : false; } +int32_t PermissionController::noteOp(const String16& op, int32_t uid, const String16& packageName) +{ + sp service = getService(); + return service != NULL ? service->noteOp(op, uid, packageName) : MODE_ERRORED; +} + void PermissionController::getPackagesForUid(const uid_t uid, Vector &packages) { sp service = getService(); diff --git a/libs/binder/include/binder/IPermissionController.h b/libs/binder/include/binder/IPermissionController.h index 2f63677026..b83d226189 100644 --- a/libs/binder/include/binder/IPermissionController.h +++ b/libs/binder/include/binder/IPermissionController.h @@ -32,6 +32,8 @@ public: virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid) = 0; + virtual int32_t noteOp(const String16& op, int32_t uid, const String16& packageName) = 0; + virtual void getPackagesForUid(const uid_t uid, Vector &packages) = 0; virtual bool isRuntimePermission(const String16& permission) = 0; @@ -40,9 +42,10 @@ public: enum { CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, - GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1, - IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2, - GET_PACKAGE_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 3 + NOTE_OP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1, + GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2, + IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 3, + GET_PACKAGE_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 4 }; }; diff --git a/libs/binder/include/binder/PermissionController.h b/libs/binder/include/binder/PermissionController.h index c4c98d02e5..cc5b6fe02b 100644 --- a/libs/binder/include/binder/PermissionController.h +++ b/libs/binder/include/binder/PermissionController.h @@ -35,9 +35,17 @@ public: MATCH_INSTANT = 1<<23 }; + enum { + MODE_ALLOWED = 0, + MODE_IGNORED = 1, + MODE_ERRORED = 2, + MODE_DEFAULT = 3, + }; + PermissionController(); bool checkPermission(const String16& permission, int32_t pid, int32_t uid); + int32_t noteOp(const String16& op, int32_t uid, const String16& packageName); void getPackagesForUid(const uid_t uid, Vector& packages); bool isRuntimePermission(const String16& permission); int getPackageUid(const String16& package, int flags); -- cgit v1.2.3-59-g8ed1b