1

I am wanting to create a custom AOSP image (based on Android 11) that includes modifications that modify behavior of core OS functions (think parental controls).

Since I'm an AOSP newbie, as a proof of concept, I created a custom system service (compiled along other aosp system services in framework/base/services/core/java/com/android/server/*). It is started in startBootstrapServices via the SystemServiceRegistry. Anyway, this service exposes one method which will try and lock the screen (a privileged operation). Code example below:

public class PocService extends IPocServiceManagerAidlInterface.Stub {
    private final static String LOG_TAG = "PocService";
    private final Context mContext;

    PocService(Context context) {
        mContext = context;
    }

    @Override
    public void lock() throws RemoteException {
        Slog.i(LOG_TAG,"PocService UID: " + android.os.Process.myUid());
        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(DevicePolicyManager.class);
        dpm.lockNow();
    }
}

My user application gets the system service and invokes the method like so:

...
PocServiceManager pocServiceManager = (PocServiceManager)getSystemService(Context.POC_SERVICE);
pocServiceManager.lock();
...

This results in an exception with the following relevant portions:

...
Caused by: java.lang.SecurityException: No active admin owned by uid 10136 for policy #3
...
...
Caused by: android.os.RemoteException: Remote stack trace:
...
at com.android.server.devicepolicy.DevicePolicyManagerService.getActiveAdminOrCheckPermissionForCallerLocked(DevicePolicyManagerService.java:3326)
at com.android.server.devicepolicy.DevicePolicyManagerService.lockNow(DevicePolicyManagerService.java:6053)
...

The UID of the POC system service is 1000 (according to the log print), and the user app is 10136.

Is there a way that I can invoke privileged operations in my custom aosp system service, which in turn I can expose an API to my user application to be able to use?

Gabe
  • 847
  • 1
  • 9
  • 16

1 Answers1

0

You should call Binder.clearCallingIdentity() before you invokes "privileged" methods, and restore it after that. This explains why you should clear calling iden

@Override
public void lock() throws RemoteException {
    Slog.i(LOG_TAG,"PocService UID: " + android.os.Process.myUid());
    final long origId = Binder.clearCallingIdentity();
    DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(DevicePolicyManager.class);
    dpm.lockNow();
    Binder.restoreCallingIdentity(origId);
}
Yong
  • 1,529
  • 12
  • 21
  • Thanks for the reply. I still get the exact same error, except instead of saying "No active admin owned by uid 10136" it says "No active admin owned by uid 1000" – Gabe Sep 10 '21 at 03:58
  • WindowManagerGlobal.getWindowManagerService().lockNow(null); Try this to lock the screen, which is used in global actions. See https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/policy/LegacyGlobalActions.java;l=508?q=lockNow&start=31 – Yong Sep 10 '21 at 05:51
  • I appreciate your response and while your method does cause the screen to lock if there is a keyguard set up, I'm not sure it answers my question. It is invoking a method that is not "privileged" as it uses PhoneWindowManager's implementation of lockNow which is not the same as DevicePolicyManager's implementation. I was wanting to know how to invoke privileged methods like DevicePolicyManager's lockNow. Can I make uid 1000 a device admin somehow? – Gabe Sep 10 '21 at 15:41
  • Looking at the code, another way is to add the LOCK_DEVICE permission. How do I add that permission to my service if it is part of the SystemServer set of system services? – Gabe Sep 10 '21 at 18:20
  • 1
    DevicePolicyManager is intend to provide API for device admin apps, which can be a third apps. And it must request user's confirm to set as an device admin app. As you see the error "No active admin owned by uid xxx", SystemServer can not be set as an device admin app. PhoneWindowManager's implementation of lockNow will require permission "android.permission.DEVICE_POWER". And you don't need to add this permission for system_server, it will bypassed by Context.enforceCallingOrSelfPermission. – Yong Sep 13 '21 at 02:02