Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9a07018 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Include GIDs for unenforced permissions.

When READ_EXTERNAL_STORAGE isn't enforced, grant its GID to all
launched processes.  When changing enforcement, kill all processes
below foreground adjustment, causing them to be relaunched with
update GIDs.

Bug: 6131916
Change-Id: I6d83efc937919f13a1a7d9caac902e572869406a
parent cae04a29
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -1055,6 +1055,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            return true;
        }

        case KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            String reason = data.readString();
            boolean res = killProcessesBelowForeground(reason);
            reply.writeNoException();
            reply.writeInt(res ? 1 : 0);
            return true;
        }

        case START_RUNNING_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            String pkg = data.readString();
@@ -2902,6 +2911,18 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
        return res;
    }
    @Override
    public boolean killProcessesBelowForeground(String reason) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeString(reason);
        mRemote.transact(KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION, data, reply, 0);
        boolean res = reply.readInt() != 0;
        data.recycle();
        reply.recycle();
        return res;
    }
    public void startRunning(String pkg, String cls, String action,
            String indata) throws RemoteException {
        Parcel data = Parcel.obtain();
+4 −2
Original line number Diff line number Diff line
@@ -218,6 +218,7 @@ public interface IActivityManager extends IInterface {
    public void noteWakeupAlarm(IIntentSender sender) throws RemoteException;

    public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException;
    public boolean killProcessesBelowForeground(String reason) throws RemoteException;

    // Special low-level communication with activity manager.
    public void startRunning(String pkg, String cls, String action,
@@ -573,4 +574,5 @@ public interface IActivityManager extends IInterface {
    int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140;
    int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
    int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
    int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143;
}
+37 −1
Original line number Diff line number Diff line
@@ -6994,6 +6994,42 @@ public final class ActivityManagerService extends ActivityManagerNative
        return killed;
    }
    @Override
    public boolean killProcessesBelowForeground(String reason) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("killProcessesBelowForeground() only available to system");
        }
        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
    }
    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("killProcessesBelowAdj() only available to system");
        }
        boolean killed = false;
        synchronized (mPidsSelfLocked) {
            final int size = mPidsSelfLocked.size();
            for (int i = 0; i < size; i++) {
                final int pid = mPidsSelfLocked.keyAt(i);
                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
                if (proc == null) continue;
                final int adj = proc.setAdj;
                if (adj > belowAdj && !proc.killedBackground) {
                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
                    EventLog.writeEvent(
                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
                    killed = true;
                    proc.killedBackground = true;
                    Process.killProcessQuiet(pid);
                }
            }
        }
        return killed;
    }
    public final void startRunning(String pkg, String cls, String action,
            String data) {
        synchronized(this) {
+23 −1
Original line number Diff line number Diff line
@@ -1577,7 +1577,16 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (p != null) {
                final PackageSetting ps = (PackageSetting)p.mExtras;
                final SharedUserSetting suid = ps.sharedUser;
                return suid != null ? suid.gids : ps.gids;
                int[] gids = suid != null ? suid.gids : ps.gids;

                // include GIDs for any unenforced permissions
                if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE)) {
                    final BasePermission basePerm = mSettings.mPermissions.get(
                            READ_EXTERNAL_STORAGE);
                    gids = appendInts(gids, basePerm.gids);
                }

                return gids;
            }
        }
        // stupid thing to indicate an error.
@@ -8854,6 +8863,19 @@ public class PackageManagerService extends IPackageManager.Stub {
                if (mSettings.mReadExternalStorageEnforcement != enforcement) {
                    mSettings.mReadExternalStorageEnforcement = enforcement;
                    mSettings.writeLPr();

                    // kill any non-foreground processes so we restart them and
                    // grant/revoke the GID.
                    final IActivityManager am = ActivityManagerNative.getDefault();
                    if (am != null) {
                        final long token = Binder.clearCallingIdentity();
                        try {
                            am.killProcessesBelowForeground("setPermissionEnforcement");
                        } catch (RemoteException e) {
                        } finally {
                            Binder.restoreCallingIdentity(token);
                        }
                    }
                }
            }
        } else {