Skip to content

Commit

Permalink
pff: permission spoofing - location
Browse files Browse the repository at this point in the history
  • Loading branch information
guhl authored and guhl committed Jan 8, 2014
1 parent 1518bbe commit bda9ad0
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 8 deletions.
5 changes: 5 additions & 0 deletions api/current.txt
Expand Up @@ -7246,6 +7246,7 @@ package android.content.pm {
method public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract java.lang.String[] getSpoofedPermissions(java.lang.String);
method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
method public abstract java.lang.String[] getSystemSharedLibraryNames();
method public abstract java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
Expand All @@ -7268,6 +7269,7 @@ package android.content.pm {
method public abstract void setApplicationEnabledSetting(java.lang.String, int, int);
method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int);
method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
method public abstract void setSpoofedPermissions(java.lang.String, java.lang.String[]);
method public abstract void verifyPendingInstall(int, int);
field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2
Expand Down Expand Up @@ -23311,6 +23313,7 @@ package android.telephony {
method public int getGsmBitErrorRate();
method public int getGsmSignalStrength();
method public boolean isGsm();
method public boolean needsOldRilFeature(java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
}

Expand Down Expand Up @@ -24096,6 +24099,7 @@ package android.test.mock {
method public android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo);
method public android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public java.lang.String[] getSpoofedPermissions(java.lang.String);
method public android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
method public java.lang.String[] getSystemSharedLibraryNames();
method public java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
Expand All @@ -24118,6 +24122,7 @@ package android.test.mock {
method public void setApplicationEnabledSetting(java.lang.String, int, int);
method public void setComponentEnabledSetting(android.content.ComponentName, int, int);
method public void setInstallerPackageName(java.lang.String, java.lang.String);
method public void setSpoofedPermissions(java.lang.String, java.lang.String[]);
method public void verifyPendingInstall(int, int);
}

Expand Down
22 changes: 21 additions & 1 deletion core/java/android/app/ContextImpl.java
Expand Up @@ -190,6 +190,11 @@ class ContextImpl extends Context {
*/
private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;

private final static boolean PFF_DEBUG = true;

private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
new HashMap<String, SharedPreferencesImpl>();

/*package*/ LoadedApk mPackageInfo;
private String mBasePackageName;
private String mOpPackageName;
Expand Down Expand Up @@ -2277,6 +2282,16 @@ private void pffEnforce(
}
}

public int pffEnforceCallingPermission(String permission, String message, int pid, int uid) {
int result = pffCheckPermission(permission, pid, uid);
// pffEnforce(permission,
// result,
// true,
// uid,
// message);
return result;
}

public int pffEnforceCallingOrSelfPermission(
String permission, String message) {
int result = pffCheckCallingOrSelfPermission(permission);
Expand All @@ -2299,16 +2314,21 @@ public int pffCheckCallingOrSelfPermission(String permission) {

public int pffCheckPermission(String permission, int pid, int uid) {
if (permission == null) {
if (PFF_DEBUG) {Log.i(TAG, "pffCheckPermission permission == null");}
throw new IllegalArgumentException("permission is null");
}

if (!Process.supportsProcesses()) {
if (PFF_DEBUG) {Log.i(TAG, "pffCheckPermission Process.supportsProcesses()=false");}
return PackageManager.PERMISSION_GRANTED;
}
try {
return ActivityManagerNative.getDefault().pffCheckPermission(
int res = ActivityManagerNative.getDefault().pffCheckPermission(
permission, pid, uid);
if (PFF_DEBUG) {Log.i(TAG, "pffCheckPermission for permission=" + permission +" uid=" + uid + " pid=" + pid + " returned="+res);}
return res;
} catch (RemoteException e) {
if (PFF_DEBUG) {Log.i(TAG, "pffCheckPermission caught RemoteException e="+e.toString());}
return PackageManager.PERMISSION_DENIED;
}
}
Expand Down
20 changes: 20 additions & 0 deletions core/java/android/content/Context.java
Expand Up @@ -2956,6 +2956,26 @@ public boolean isRestricted() {
return false;
}


/**
* If neither you nor the calling process of an IPC you are
* handling has been granted a particular permission or the permission is
* revoked , throw a {@link SecurityException}. If the calling
* process or you have the permission spoofed.
* {@link PackageManager#PERMISSION_SPOOFED} is returned.
* If the permission is granted {@link PackageManager#PERMISSION_GRANTED}
* is returned.
*
* @param permission The name of the permission being checked.
* @param message A message to include in the exception if it is thrown.
* @param pid the process id for which the permission is checked.
* @param uid the process id for which the permission is checked.
*
* @see #pffCheckCallingOrSelfPermission(String)
* @hide
*/
public abstract int pffEnforceCallingPermission(String permission, String message, int pid, int uid);

/**
* If neither you nor the calling process of an IPC you are
* handling has been granted a particular permission or the permission is
Expand Down
7 changes: 7 additions & 0 deletions core/java/android/content/ContextWrapper.java
Expand Up @@ -671,6 +671,13 @@ public DisplayAdjustments getDisplayAdjustments(int displayId) {
return mBase.getDisplayAdjustments(displayId);
}

/**
* @hide
*/
@Override
public int pffEnforceCallingPermission(String permission, String message, int pid, int uid) {
return mBase.pffEnforceCallingPermission(permission, message, pid, uid);
}
/**
* @hide
*/
Expand Down
4 changes: 1 addition & 3 deletions core/java/android/content/pm/PackageManager.java
Expand Up @@ -3252,7 +3252,6 @@ public static String getDataDirForUser(int userId, String packageName) {
* uid will be returned.
*
* @param packageName Name of the package which revoked permissions are needed
* @hide
*/

public abstract String[] getSpoofedPermissions(String packageName);
Expand All @@ -3264,8 +3263,7 @@ public static String getDataDirForUser(int userId, String packageName) {
* permissions for that shared uid.
*
* @param packageName Name of the package which revoked permissions are needed
* @param the spoofed permissions.
* @hide
* @param perms the spoofed permissions.
*/
public abstract void setSpoofedPermissions(String packageName, String[] perms);

Expand Down
2 changes: 2 additions & 0 deletions core/java/android/widget/AppSecurityPermissionsBase.java
Expand Up @@ -9,4 +9,6 @@ public abstract class AppSecurityPermissionsBase {
public abstract View getPermissionsView();

public abstract int getPermissionCount();

public abstract View getPermissionsViewWithRevokeButtons();
}
2 changes: 2 additions & 0 deletions core/res/res/xml/spoofed_permissions.xml
Expand Up @@ -5,4 +5,6 @@ If you add anything here make sure that the implementation DO support protecting

<spoofed-perms>
<item name="android.permission.READ_PHONE_STATE" />
<item name="android.permission.ACCESS_COARSE_LOCATION" />
<item name="android.permission.ACCESS_FINE_LOCATION" />
</spoofed-perms>
60 changes: 56 additions & 4 deletions services/java/com/android/server/LocationManagerService.java
Expand Up @@ -17,6 +17,8 @@
package com.android.server;

import android.app.AppOpsManager;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
Expand Down Expand Up @@ -96,6 +98,7 @@
public class LocationManagerService extends ILocationManager.Stub {
private static final String TAG = "LocationManagerService";
public static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
public static final boolean PFF_D = true;

private static final String WAKELOCK_KEY = TAG;

Expand Down Expand Up @@ -1605,7 +1608,6 @@ public Location getLastLocation(LocationRequest request, String packageName) {
packageName);
return null;
}

if (!reportLocationAccessNoThrow(uid, packageName, allowedResolutionLevel)) {
if (D) Log.d(TAG, "not returning last loc for no op app: " +
packageName);
Expand Down Expand Up @@ -1633,6 +1635,7 @@ public Location getLastLocation(LocationRequest request, String packageName) {
if (location == null) {
return null;
}

if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) {
Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
if (noGPSLocation != null) {
Expand Down Expand Up @@ -1898,8 +1901,8 @@ public void reportLocation(Location location, boolean passive) {
Log.w(TAG, "Dropping incomplete location: " + location);
return;
}

mLocationHandler.removeMessages(MSG_LOCATION_CHANGED, location);

Message m = Message.obtain(mLocationHandler, MSG_LOCATION_CHANGED, location);
m.arg1 = (passive ? 1 : 0);
mLocationHandler.sendMessageAtFrontOfQueue(m);
Expand Down Expand Up @@ -1942,13 +1945,61 @@ private static boolean shouldBroadcastSafe(
return true;
}

private String getAppNameByPID(Context context, int pid){
ActivityManager manager
= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

for(RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()){
if(processInfo.pid == pid){
return processInfo.processName;
}
}
return "";
}

private Location spoofLocation(Location location, int pid, int uid){

String appName = "";
if (PFF_D){
appName = getAppNameByPID(mContext, pid);
}
int res_f = mContext.pffEnforceCallingPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,
"Requires ACCESS_FINE_LOCATION", pid, uid);
if (PFF_D) {Log.d(TAG, "spoofLocation: pffEnforceCallingPermission ACCESS_FINE_LOCATION pid="+pid+" uid="+uid+" appName="+appName+" res="+res_f);}
int res_c = mContext.pffEnforceCallingPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION,
"Requires ACCESS_COARSE_LOCATION", pid, uid);
if (PFF_D) {Log.d(TAG, "spoofLocation: pffEnforceCallingPermission ACCESS_COARSE_LOCATION pid="+pid+" uid="+uid+" appName="+appName+" res="+res_c);}
if (location!=null){
if (res_f==PackageManager.PERMISSION_SPOOFED){
if (PFF_D) {Log.d(TAG, "spoofLocation: FINE spoofed");}
location.setLatitude(27.988056);
location.setLongitude(86.925278);
location.setAltitude(8848.0);
}
Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
if (noGPSLocation!=null) {
if (res_c==PackageManager.PERMISSION_SPOOFED ||
(res_c!=PackageManager.PERMISSION_GRANTED && res_f==PackageManager.PERMISSION_SPOOFED) ){
if (PFF_D) {Log.d(TAG, "spoofLocation: COARSE spoofed");}
noGPSLocation.setLatitude(27.988056);
noGPSLocation.setLongitude(86.925278);
noGPSLocation.setAltitude(8848.0);
location.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, noGPSLocation);
}
}

}
return location;
}

private void handleLocationChangedLocked(Location location, boolean passive) {
if (D) Log.d(TAG, "incoming location: " + location);

if (D || PFF_D) Log.d(TAG, "incoming location: " + location);

long now = SystemClock.elapsedRealtime();
String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider());

// Skip if the provider is unknown.
// Skip if thse provider is unknown.
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null) return;

Expand Down Expand Up @@ -2040,6 +2091,7 @@ private void handleLocationChangedLocked(Location location, boolean passive) {
} else {
notifyLocation = lastLocation; // use fine location
}
notifyLocation = spoofLocation(notifyLocation, receiver.mPid, receiver.mUid);
if (notifyLocation != null) {
Location lastLoc = r.mLastFixBroadcast;
if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r, now)) {
Expand Down
8 changes: 8 additions & 0 deletions test-runner/src/android/test/mock/MockContext.java
Expand Up @@ -599,6 +599,14 @@ public File[] getExternalCacheDirs() {
throw new UnsupportedOperationException();
}

/**
* @hide
*/
@Override
public int pffEnforceCallingPermission(String permission, String message, int pid, int uid) {
throw new UnsupportedOperationException();
}

/**
* @hide
*/
Expand Down
Expand Up @@ -1435,6 +1435,10 @@ public File[] getExternalCacheDirs() {
return new File[0];
}

public int pffEnforceCallingPermission(String permission, String message, int pid, int uid) {
return 0;
}

public int pffEnforceCallingOrSelfPermission(String permission, String message) {
return 0;
}
Expand Down

0 comments on commit bda9ad0

Please sign in to comment.