Fix uid to package name mapping in MatchList

PCAPdroid assumes a persistent mapping between a uid and a package name.
However, this mapping may change if an app sharing its uid is
installed/removed. This resulted in the inability to remove an existing
app rule from a MatchList. This fix only addresses the change at load
time, whereas the problem may still occur at runtime.

Fixes #257
This commit is contained in:
emanuele-f 2022-09-20 16:51:30 +02:00
parent 0b34620233
commit d10fa01824
2 changed files with 20 additions and 7 deletions

View File

@ -93,6 +93,7 @@ public class AppsResolver {
// Get the AppDescriptor corresponding to the given package name
// No caching occurs. Virtual apps cannot be used.
// This is public to provide a fast resolution alternative to getAppByPackage
public static AppDescriptor resolveInstalledApp(PackageManager pm, String packageName, int pm_flags) {
PackageInfo pinfo;
@ -129,7 +130,9 @@ public class AppsResolver {
}
// Impose order to guarantee that a uid is always mapped to the same package name.
//
// The mapping may change if a package sharing this UID is installed/removed.
// For simplicity we ignore this change at runtime, and only address it in persistent data
// (e.g. in the MatchList to ensure that a user can always remove rules see #257)
String packageName = packages[0];
for(String pkg: packages) {
if(pkg.compareTo(packageName) < 0)

View File

@ -61,7 +61,7 @@ public class MatchList {
private final ArrayMap<String, Rule> mMatches = new ArrayMap<>();
private final ArraySet<Integer> mUids = new ArraySet<>();
private final AppsResolver mResolver;
private boolean mFormatMigration = false;
private boolean mMigration = false;
public enum RuleType {
APP,
@ -129,10 +129,10 @@ public class MatchList {
if(!serialized.isEmpty()) {
fromJson(serialized);
if(mFormatMigration) {
if(mMigration) {
Log.i(TAG, "Migration completed");
save();
mFormatMigration = false;
mMigration = false;
}
} else
clear();
@ -211,15 +211,15 @@ public class MatchList {
if(typeStr.equals("ROOT_DOMAIN")) {
Log.i(TAG, String.format("ROOT_DOMAIN %s migrated", val));
type = RuleType.HOST;
mFormatMigration = true;
mMigration = true;
} else {
e.printStackTrace();
continue;
}
}
// Handle migration from old uid-based format
if(type == RuleType.APP) {
// Handle migration from the old uid-based format
try {
int uid = Integer.parseInt(val);
@ -227,7 +227,7 @@ public class MatchList {
if(app != null) {
val = app.getPackageName();
Log.i(TAG, String.format("UID %d resolved to package %s", uid, val));
mFormatMigration = true;
mMigration = true;
} else {
Log.w(TAG, "Ignoring unknown UID " + uid);
continue;
@ -235,6 +235,16 @@ public class MatchList {
} catch (NumberFormatException ignored) {
// ok, package name
}
// Validate the uid->package_name mapping (see AppsResolver for more details).
// If the uid is mapped to a different package name, we must update the MatchList
// otherwise the user may not be able to remove the rule (see #257).
AppDescriptor app = mResolver.getAppByPackage(val, 0);
if((app != null) && !app.getPackageName().equals(val)) {
Log.i(TAG, "The UID " + app.getUid() + " mapping has changed from " + val + " to " + app.getPackageName());
val = app.getPackageName();
mMigration = true;
}
}
addRule(new Rule(type, val));