Merge "Fix privacy leaks in LocationManager" into mnc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f7340e754e
@@ -892,7 +892,6 @@ public class LocationManager {
|
|||||||
* @param listener listener object that no longer needs location updates
|
* @param listener listener object that no longer needs location updates
|
||||||
* @throws IllegalArgumentException if listener is null
|
* @throws IllegalArgumentException if listener is null
|
||||||
*/
|
*/
|
||||||
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
|
|
||||||
public void removeUpdates(LocationListener listener) {
|
public void removeUpdates(LocationListener listener) {
|
||||||
checkListener(listener);
|
checkListener(listener);
|
||||||
String packageName = mContext.getPackageName();
|
String packageName = mContext.getPackageName();
|
||||||
@@ -1055,7 +1054,6 @@ public class LocationManager {
|
|||||||
* @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
|
* @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
|
||||||
* permission is not present
|
* permission is not present
|
||||||
*/
|
*/
|
||||||
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
|
|
||||||
public void removeProximityAlert(PendingIntent intent) {
|
public void removeProximityAlert(PendingIntent intent) {
|
||||||
checkPendingIntent(intent);
|
checkPendingIntent(intent);
|
||||||
String packageName = mContext.getPackageName();
|
String packageName = mContext.getPackageName();
|
||||||
@@ -1083,7 +1081,6 @@ public class LocationManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
|
|
||||||
public void removeGeofence(Geofence fence, PendingIntent intent) {
|
public void removeGeofence(Geofence fence, PendingIntent intent) {
|
||||||
checkPendingIntent(intent);
|
checkPendingIntent(intent);
|
||||||
checkGeofence(fence);
|
checkGeofence(fence);
|
||||||
@@ -1107,7 +1104,6 @@ public class LocationManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
|
|
||||||
public void removeAllGeofences(PendingIntent intent) {
|
public void removeAllGeofences(PendingIntent intent) {
|
||||||
checkPendingIntent(intent);
|
checkPendingIntent(intent);
|
||||||
String packageName = mContext.getPackageName();
|
String packageName = mContext.getPackageName();
|
||||||
|
|||||||
@@ -270,6 +270,17 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
};
|
};
|
||||||
mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback);
|
mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback);
|
||||||
|
|
||||||
|
PackageManager.OnPermissionsChangedListener permissionListener
|
||||||
|
= new PackageManager.OnPermissionsChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void onPermissionsChanged(final int uid) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
applyAllProviderRequirementsLocked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mPackageManager.addOnPermissionsChangeListener(permissionListener);
|
||||||
|
|
||||||
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||||
updateUserProfiles(mCurrentUserId);
|
updateUserProfiles(mCurrentUserId);
|
||||||
|
|
||||||
@@ -1133,23 +1144,34 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean reportLocationAccessNoThrow(int uid, String packageName, int allowedResolutionLevel) {
|
boolean reportLocationAccessNoThrow(
|
||||||
|
int pid, int uid, String packageName, int allowedResolutionLevel) {
|
||||||
int op = resolutionLevelToOp(allowedResolutionLevel);
|
int op = resolutionLevelToOp(allowedResolutionLevel);
|
||||||
if (op >= 0) {
|
if (op >= 0) {
|
||||||
if (mAppOps.noteOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
|
if (mAppOps.noteOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getAllowedResolutionLevel(pid, uid) < allowedResolutionLevel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean checkLocationAccess(int uid, String packageName, int allowedResolutionLevel) {
|
boolean checkLocationAccess(int pid, int uid, String packageName, int allowedResolutionLevel) {
|
||||||
int op = resolutionLevelToOp(allowedResolutionLevel);
|
int op = resolutionLevelToOp(allowedResolutionLevel);
|
||||||
if (op >= 0) {
|
if (op >= 0) {
|
||||||
if (mAppOps.checkOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
|
if (mAppOps.checkOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getAllowedResolutionLevel(pid, uid) < allowedResolutionLevel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1347,7 +1369,10 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
if (records != null) {
|
if (records != null) {
|
||||||
for (UpdateRecord record : records) {
|
for (UpdateRecord record : records) {
|
||||||
if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) {
|
if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) {
|
||||||
if (checkLocationAccess(record.mReceiver.mUid, record.mReceiver.mPackageName,
|
if (checkLocationAccess(
|
||||||
|
record.mReceiver.mPid,
|
||||||
|
record.mReceiver.mUid,
|
||||||
|
record.mReceiver.mPackageName,
|
||||||
record.mReceiver.mAllowedResolutionLevel)) {
|
record.mReceiver.mAllowedResolutionLevel)) {
|
||||||
LocationRequest locationRequest = record.mRequest;
|
LocationRequest locationRequest = record.mRequest;
|
||||||
providerRequest.locationRequests.add(locationRequest);
|
providerRequest.locationRequests.add(locationRequest);
|
||||||
@@ -1583,7 +1608,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
try {
|
try {
|
||||||
// We don't check for MODE_IGNORED here; we will do that when we go to deliver
|
// We don't check for MODE_IGNORED here; we will do that when we go to deliver
|
||||||
// a location.
|
// a location.
|
||||||
checkLocationAccess(uid, packageName, allowedResolutionLevel);
|
checkLocationAccess(pid, uid, packageName, allowedResolutionLevel);
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid,
|
Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid,
|
||||||
@@ -1711,6 +1736,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
request.getProvider());
|
request.getProvider());
|
||||||
// no need to sanitize this request, as only the provider name is used
|
// no need to sanitize this request, as only the provider name is used
|
||||||
|
|
||||||
|
final int pid = Binder.getCallingPid();
|
||||||
final int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
final long identity = Binder.clearCallingIdentity();
|
final long identity = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
@@ -1720,7 +1746,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reportLocationAccessNoThrow(uid, packageName, allowedResolutionLevel)) {
|
if (!reportLocationAccessNoThrow(pid, uid, packageName, allowedResolutionLevel)) {
|
||||||
if (D) Log.d(TAG, "not returning last loc for no op app: " +
|
if (D) Log.d(TAG, "not returning last loc for no op app: " +
|
||||||
packageName);
|
packageName);
|
||||||
return null;
|
return null;
|
||||||
@@ -1794,7 +1820,6 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) {
|
public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) {
|
||||||
checkResolutionLevelIsSufficientForGeofenceUse(getCallerAllowedResolutionLevel());
|
|
||||||
checkPendingIntent(intent);
|
checkPendingIntent(intent);
|
||||||
checkPackageName(packageName);
|
checkPackageName(packageName);
|
||||||
|
|
||||||
@@ -1816,10 +1841,11 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
|
checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
|
||||||
LocationManager.GPS_PROVIDER);
|
LocationManager.GPS_PROVIDER);
|
||||||
|
|
||||||
|
final int pid = Binder.getCallingPid();
|
||||||
final int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
final long ident = Binder.clearCallingIdentity();
|
final long ident = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
if (!checkLocationAccess(uid, packageName, allowedResolutionLevel)) {
|
if (!checkLocationAccess(pid, uid, packageName, allowedResolutionLevel)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1859,11 +1885,12 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
allowedResolutionLevel,
|
allowedResolutionLevel,
|
||||||
LocationManager.GPS_PROVIDER);
|
LocationManager.GPS_PROVIDER);
|
||||||
|
|
||||||
|
int pid = Binder.getCallingPid();
|
||||||
int uid = Binder.getCallingUid();
|
int uid = Binder.getCallingUid();
|
||||||
long identity = Binder.clearCallingIdentity();
|
long identity = Binder.clearCallingIdentity();
|
||||||
boolean hasLocationAccess;
|
boolean hasLocationAccess;
|
||||||
try {
|
try {
|
||||||
hasLocationAccess = checkLocationAccess(uid, packageName, allowedResolutionLevel);
|
hasLocationAccess = checkLocationAccess(pid, uid, packageName, allowedResolutionLevel);
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(identity);
|
Binder.restoreCallingIdentity(identity);
|
||||||
}
|
}
|
||||||
@@ -1890,11 +1917,12 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
allowedResolutionLevel,
|
allowedResolutionLevel,
|
||||||
LocationManager.GPS_PROVIDER);
|
LocationManager.GPS_PROVIDER);
|
||||||
|
|
||||||
|
int pid = Binder.getCallingPid();
|
||||||
int uid = Binder.getCallingUid();
|
int uid = Binder.getCallingUid();
|
||||||
long identity = Binder.clearCallingIdentity();
|
long identity = Binder.clearCallingIdentity();
|
||||||
boolean hasLocationAccess;
|
boolean hasLocationAccess;
|
||||||
try {
|
try {
|
||||||
hasLocationAccess = checkLocationAccess(uid, packageName, allowedResolutionLevel);
|
hasLocationAccess = checkLocationAccess(pid, uid, packageName, allowedResolutionLevel);
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(identity);
|
Binder.restoreCallingIdentity(identity);
|
||||||
}
|
}
|
||||||
@@ -2209,7 +2237,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reportLocationAccessNoThrow(receiver.mUid, receiver.mPackageName,
|
if (!reportLocationAccessNoThrow(receiver.mPid, receiver.mUid, receiver.mPackageName,
|
||||||
receiver.mAllowedResolutionLevel)) {
|
receiver.mAllowedResolutionLevel)) {
|
||||||
if (D) Log.d(TAG, "skipping loc update for no op app: " +
|
if (D) Log.d(TAG, "skipping loc update for no op app: " +
|
||||||
receiver.mPackageName);
|
receiver.mPackageName);
|
||||||
|
|||||||
Reference in New Issue
Block a user