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

Commit 0a17db1c authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Detect non-oneway calls leaving system_server.

To protect system stability, any Binder calls leaving the
system_server must carefully be performed using FLAG_ONEWAY (or
the 'oneway' verb in AIDL) which prevents the call from blocking
indefinitely on the remote process.

In this CL, the system_server uses the new Binder.setWarnOnBlocking()
method to enable detection by default for all remote Binder
interfaces.  It can also use Binder.allowBlocking() to allow
blocking calls on certain remote interfaces that have been
determined to be safe.

This CL adds the 'oneway' verb to several interfaces and methods
where it should have been added, and marks a handful of system
ContentProviders as being safe to call into.  Also, we assume that
any services obtained from ServiceManager are part of the core
OS, and are okay to make blocking calls to.

Test: builds, boots, runs with minimal logs triggered
Bug: 32715088
Change-Id: Ide476e120cb40436a94b7faf7615c943d691f4c0
parent 9d710882
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -80,6 +80,11 @@ import android.os.SystemProperties;
import android.os.Trace;
import android.os.TransactionTooLargeException;
import android.os.UserHandle;
import android.provider.BlockedNumberContract;
import android.provider.CalendarContract;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.provider.Downloads;
import android.provider.Settings;
import android.security.NetworkSecurityPolicy;
import android.security.net.config.NetworkSecurityConfigProvider;
@@ -5823,6 +5828,22 @@ public final class ActivityThread {
        final String auths[] = holder.info.authority.split(";");
        final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);

        if (provider != null) {
            // If this provider is hosted by the core OS and cannot be upgraded,
            // then I guess we're okay doing blocking calls to it.
            for (String auth : auths) {
                switch (auth) {
                    case ContactsContract.AUTHORITY:
                    case CallLog.AUTHORITY:
                    case CallLog.SHADOW_AUTHORITY:
                    case BlockedNumberContract.AUTHORITY:
                    case CalendarContract.AUTHORITY:
                    case Downloads.Impl.AUTHORITY:
                        Binder.allowBlocking(provider.asBinder());
                }
            }
        }

        final ProviderClientRecord pcr = new ProviderClientRecord(
                auths, provider, localProvider, holder);
        for (String auth : auths) {
@@ -5971,7 +5992,6 @@ public final class ActivityThread {
                retHolder = prc.holder;
            }
        }

        return retHolder;
    }

+2 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.media.AudioManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
@@ -572,7 +573,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
            if (DBG) Log.d(TAG, "Proxy object connected");
            try {
                mServiceLock.writeLock().lock();
                mService = IBluetoothA2dp.Stub.asInterface(service);
                mService = IBluetoothA2dp.Stub.asInterface(Binder.allowBlocking(service));
            } finally {
                mServiceLock.writeLock().unlock();
            }
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -481,7 +482,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
    private final ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            if (DBG) Log.d(TAG, "Proxy object connected");
            mService = IBluetoothA2dpSink.Stub.asInterface(service);
            mService = IBluetoothA2dpSink.Stub.asInterface(Binder.allowBlocking(service));

            if (mServiceListener != null) {
                mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK,
+2 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.media.MediaMetadata;
import android.media.session.PlaybackState;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -284,7 +285,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
    private final ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            if (DBG) Log.d(TAG, "Proxy object connected");
            mService = IBluetoothAvrcpController.Stub.asInterface(service);
            mService = IBluetoothAvrcpController.Stub.asInterface(Binder.allowBlocking(service));

            if (mServiceListener != null) {
                mServiceListener.onServiceConnected(BluetoothProfile.AVRCP_CONTROLLER,
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
import android.content.Context;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -1037,7 +1038,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            if (DBG) Log.d(TAG, "Proxy object connected");
            mService = IBluetoothHeadset.Stub.asInterface(service);
            mService = IBluetoothHeadset.Stub.asInterface(Binder.allowBlocking(service));
            mHandler.sendMessage(mHandler.obtainMessage(
                    MESSAGE_HEADSET_SERVICE_CONNECTED));
        }
Loading