Skip to content

Commit

Permalink
Fix app not blocked after reinstallation
Browse files Browse the repository at this point in the history
The package name to UID mapping was not updated after reinstallation,
causing UID matching to fail and subsequent failure to block it.
Now the UID mapping is automatically updated whenever an app is
installed or uninstalled.

Fixes #338
  • Loading branch information
emanuele-f committed Aug 11, 2023
1 parent e2c5b81 commit 68daa31
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -509,17 +509,19 @@ public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
boolean newInstall = !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
String packageName = intent.getData().getSchemeSpecificPart();
Log.i(TAG, "ACTION_PACKAGE_ADDED [new=" + newInstall + "]: " + packageName);

if(newInstall && Prefs.blockNewApps(mPrefs)) {
Log.i(TAG, "Blocking newly installed app: " + packageName);
mBlocklist.addApp(packageName);
if(!mBlocklist.addApp(packageName))
return;

mBlocklist.save();
reloadBlocklist();

AppDescriptor app = AppsResolver.resolveInstalledApp(getPackageManager(), packageName, 0);
String label = (app != null) ? app.getName() : packageName;

Log.i(TAG, "Blocking newly installed app: " + packageName + ((app != null) ? " - " + app.getUid() : ""));

PendingIntent pi = PendingIntent.getActivity(CaptureService.this, 0,
new Intent(CaptureService.this, FirewallActivity.class), Utils.getIntentFlags(0));

Expand Down
54 changes: 54 additions & 0 deletions app/src/main/java/com/emanuelef/remote_capture/PCAPdroid.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
package com.emanuelef.remote_capture;

import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;

import androidx.annotation.NonNull;
Expand Down Expand Up @@ -92,6 +95,32 @@ public void onCreate() {
theme = "system";
}
Utils.setAppTheme(theme);

// Listen to package events
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
boolean newInstall = !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
String packageName = intent.getData().getSchemeSpecificPart();
Log.d(TAG, "ACTION_PACKAGE_ADDED [new=" + newInstall + "]: " + packageName);

if(newInstall)
checkUidMapping(packageName);
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
boolean isUpdate = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
String packageName = intent.getData().getSchemeSpecificPart();
Log.d(TAG, "ACTION_PACKAGE_REMOVED [update=" + isUpdate + "]: " + packageName);

if(!isUpdate)
checkUidMapping(packageName);
}
}
}, filter);
}

public static @NonNull PCAPdroid getInstance() {
Expand Down Expand Up @@ -141,6 +170,31 @@ private void initFirewallWhitelist() {
mFirewallWhitelist.save();
}

private void checkUidMapping(String pkg) {
if(mVisMask != null)
mVisMask.uidMappingChanged(pkg);

// When an app is installed/uninstalled, recheck the UID mappings.
// In particular:
// - On app uninstall, invalidate any package_name -> UID mapping
// - On app install, add the new package_name -> UID mapping
if((mMalwareWhitelist != null) && mMalwareWhitelist.uidMappingChanged(pkg))
CaptureService.reloadMalwareWhitelist();

if((mFirewallWhitelist != null) && mFirewallWhitelist.uidMappingChanged(pkg)) {
if(CaptureService.isServiceActive())
CaptureService.requireInstance().reloadFirewallWhitelist();
}

if((mDecryptionList != null) && mDecryptionList.uidMappingChanged(pkg))
CaptureService.reloadDecryptionList();

if((mBlocklist != null) && mBlocklist.uidMappingChanged(pkg)) {
if(CaptureService.isServiceActive())
CaptureService.requireInstance().reloadBlocklist();
}
}

public MatchList getFirewallWhitelist() {
if(mFirewallWhitelist == null) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class MatchList {
private final ArrayList<Rule> mRules = new ArrayList<>();
private final ArrayMap<String, Rule> mMatches = new ArrayMap<>();
private final ArraySet<Integer> mUids = new ArraySet<>();
private final ArrayMap<String, Integer> mPackageToUid = new ArrayMap<>();
private final AppsResolver mResolver;
private boolean mMigration = false;

Expand Down Expand Up @@ -314,6 +315,7 @@ private boolean addRule(Rule rule, boolean notify) {
if(uid == Utils.UID_NO_FILTER)
return false;

mPackageToUid.put(value, uid);
mUids.add(uid);
}

Expand Down Expand Up @@ -352,9 +354,10 @@ public void removeRule(Rule rule) {

if(rule.getType() == RuleType.APP) {
int uid = mResolver.getUid(val);
if(uid != Utils.UID_NO_FILTER)
if(uid != Utils.UID_NO_FILTER) {
mPackageToUid.remove(val);
mUids.remove(uid);
else
} else
Log.w(TAG, "removeRule: no uid found for package " + val);
}

Expand Down Expand Up @@ -417,6 +420,7 @@ public void clear(boolean notify) {
boolean hasRules = mRules.size() > 0;
mRules.clear();
mMatches.clear();
mPackageToUid.clear();
mUids.clear();

if(notify && hasRules)
Expand Down Expand Up @@ -510,4 +514,37 @@ private void notifyListeners() {
for(ListChangeListener listener: mListeners)
listener.onListChanged();
}

/* Call this whenever a package name -> uid mapping may have changed.
* True is returned when the mapping has been updated. In such a case,
* the caller must reload any native rules based on this MatchList. */
public boolean uidMappingChanged(String pkg) {
if(!mMatches.containsKey(matchKey(RuleType.APP, pkg)))
return false;

boolean changed = false;
Integer old_uid = mPackageToUid.get(pkg);
AppDescriptor app = mResolver.getAppByPackage(pkg, 0);

if((old_uid != null) && ((app == null) || (app.getUid() != old_uid))) {
Log.i(TAG, "Remove old UID mapping of " + pkg + ": " + old_uid);

mPackageToUid.remove(pkg);
mUids.remove(old_uid);
changed = true;

old_uid = null; // possibly add the new UID mapping below
}

if((old_uid == null) && (app != null)) {
int new_uid = app.getUid();
Log.i(TAG, "Add UID mapping of " + pkg + ": " + new_uid);

mPackageToUid.put(pkg, new_uid);
mUids.add(new_uid);
changed = true;
}

return changed;
}
}

0 comments on commit 68daa31

Please sign in to comment.