summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2016-11-04 11:23:46 -0600
committerJeff Sharkey <jsharkey@android.com>2016-11-07 17:03:37 -0700
commit0a17db1cc5942ea000ca87bb72853de57a15ec64 (patch)
tree7a0b51064dc654901bd69857c2f3a14fe8d5871a
parent9d710882602a8a0ad661cf10ce2cb421f3255ee2 (diff)
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
-rw-r--r--core/java/android/app/ActivityThread.java22
-rw-r--r--core/java/android/bluetooth/BluetoothA2dp.java3
-rwxr-xr-xcore/java/android/bluetooth/BluetoothA2dpSink.java3
-rw-r--r--core/java/android/bluetooth/BluetoothAvrcpController.java3
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java3
-rw-r--r--core/java/android/bluetooth/BluetoothHeadsetClient.java3
-rw-r--r--core/java/android/bluetooth/BluetoothHealth.java3
-rw-r--r--core/java/android/bluetooth/BluetoothInputDevice.java3
-rw-r--r--core/java/android/bluetooth/BluetoothMap.java2
-rw-r--r--core/java/android/bluetooth/BluetoothPan.java3
-rw-r--r--core/java/android/bluetooth/BluetoothPbapClient.java3
-rw-r--r--core/java/android/bluetooth/BluetoothSap.java3
-rwxr-xr-xcore/java/android/bluetooth/IBluetoothHeadset.aidl2
-rwxr-xr-xcore/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl2
-rw-r--r--core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl2
-rw-r--r--core/java/android/content/ContentProviderNative.java1
-rw-r--r--core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl2
-rw-r--r--core/java/android/os/Binder.java87
-rw-r--r--core/java/android/os/ServiceManager.java7
-rw-r--r--core/java/android/provider/Downloads.java2
-rw-r--r--keystore/java/android/security/KeyChain.java3
-rw-r--r--location/java/android/location/IGeofenceProvider.aidl2
-rw-r--r--media/java/android/media/IRingtonePlayer.aidl10
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java5
-rw-r--r--services/core/java/com/android/server/MmsServiceBroker.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java3
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java7
-rw-r--r--services/java/com/android/server/SystemServer.java4
28 files changed, 148 insertions, 47 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 3e8d90bf62ed..a3414f458ef3 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -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;
}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 353c6400ffd7..3de159a6cff2 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -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();
}
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index 74302f27ec1d..9dfc4b442fa4 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -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,
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index a395aa470f5b..0261b1b35e2d 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -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,
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index f46a3b3c733a..28421ebc4cca 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -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));
}
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 93790feecd11..c7c64c4391c2 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -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.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
@@ -1122,7 +1123,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothHeadsetClient.Stub.asInterface(service);
+ mService = IBluetoothHeadsetClient.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.HEADSET_CLIENT,
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 4949c24372a4..8d77888193b6 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -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.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -522,7 +523,7 @@ public final class BluetoothHealth implements BluetoothProfile {
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothHealth.Stub.asInterface(service);
+ mService = IBluetoothHealth.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.HEALTH, BluetoothHealth.this);
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index 252e3d28a25e..e3288f3c7c88 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -22,6 +22,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;
@@ -479,7 +480,7 @@ public final class BluetoothInputDevice implements BluetoothProfile {
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
- mService = IBluetoothInputDevice.Stub.asInterface(service);
+ mService = IBluetoothInputDevice.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this);
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 7f57acf3dc63..2e73051ee610 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -371,7 +371,7 @@ public final class BluetoothMap implements BluetoothProfile {
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) log("Proxy object connected");
- mService = IBluetoothMap.Stub.asInterface(service);
+ mService = IBluetoothMap.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.MAP, BluetoothMap.this);
}
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 744f9421b239..2a026a91e8e6 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -22,6 +22,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;
@@ -368,7 +369,7 @@ public final class BluetoothPan implements BluetoothProfile {
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "BluetoothPAN Proxy object connected");
- mPanService = IBluetoothPan.Stub.asInterface(service);
+ mPanService = IBluetoothPan.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.PAN,
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index eab4c6f5130c..9f00e1aaa3a1 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.RemoteException;
+import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
@@ -288,7 +289,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
if (DBG) {
log("Proxy object connected");
}
- mService = IBluetoothPbapClient.Stub.asInterface(service);
+ mService = IBluetoothPbapClient.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT, BluetoothPbapClient.this);
}
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index e70c936e253e..89c1bf8f9aa2 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.RemoteException;
+import android.os.Binder;
import android.os.IBinder;
import android.os.ServiceManager;
import android.util.Log;
@@ -393,7 +394,7 @@ public final class BluetoothSap implements BluetoothProfile {
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) log("Proxy object connected");
- mService = IBluetoothSap.Stub.asInterface(service);
+ mService = IBluetoothSap.Stub.asInterface(Binder.allowBlocking(service));
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.SAP, BluetoothSap.this);
}
diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl
index 6ad442b6138d..dde0ac67bbb5 100755
--- a/core/java/android/bluetooth/IBluetoothHeadset.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl
@@ -54,7 +54,7 @@ interface IBluetoothHeadset {
boolean getAudioRouteAllowed();
boolean startScoUsingVirtualVoiceCall(in BluetoothDevice device);
boolean stopScoUsingVirtualVoiceCall(in BluetoothDevice device);
- void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
+ oneway void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
void clccResponse(int index, int direction, int status, int mode, boolean mpty,
String number, int type);
boolean enableWBS();
diff --git a/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl b/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl
index 96c59e239151..541583ff5535 100755
--- a/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl
+++ b/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl
@@ -24,7 +24,7 @@ import android.os.IBinder;
*
* {@hide}
*/
-interface IBluetoothProfileServiceConnection {
+oneway interface IBluetoothProfileServiceConnection {
void onServiceConnected(in ComponentName comp, in IBinder service);
void onServiceDisconnected(in ComponentName comp);
}
diff --git a/core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl b/core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl
index feccdce57b98..0da4e8843282 100644
--- a/core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl
@@ -21,7 +21,7 @@ package android.bluetooth;
*
* {@hide}
*/
-interface IBluetoothStateChangeCallback
+oneway interface IBluetoothStateChangeCallback
{
void onBluetoothStateChange(boolean on);
}
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 4769bd02a5dc..439e1ff48c17 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -422,6 +422,7 @@ final class ContentProviderProxy implements IContentProvider
if (reply.readInt() != 0) {
BulkCursorDescriptor d = BulkCursorDescriptor.CREATOR.createFromParcel(reply);
+ Binder.copyAllowBlocking(mRemote, (d.cursor != null) ? d.cursor.asBinder() : null);
adaptor.initialize(d);
} else {
adaptor.close();
diff --git a/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl b/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl
index d2c3d7555e70..3fe645c59a30 100644
--- a/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl
+++ b/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl
@@ -25,7 +25,7 @@ import android.hardware.location.IActivityRecognitionHardware;
*
* @hide
*/
-interface IActivityRecognitionHardwareClient {
+oneway interface IActivityRecognitionHardwareClient {
/**
* Hardware Activity-Recognition availability event.
*
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 7b7533b16410..01369791fd38 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -75,36 +75,35 @@ public class Binder implements IBinder {
/**
* Control whether dump() calls are allowed.
*/
- private static String sDumpDisabled = null;
+ private static volatile String sDumpDisabled = null;
/**
* Global transaction tracker instance for this process.
*/
- private static TransactionTracker sTransactionTracker = null;
+ private static volatile TransactionTracker sTransactionTracker = null;
// Transaction tracking code.
/**
* Flag indicating whether we should be tracing transact calls.
- *
*/
- private static boolean sTracingEnabled = false;
+ private static volatile boolean sTracingEnabled = false;
/**
* Enable Binder IPC tracing.
*
* @hide
*/
- public static void enableTracing() {
+ public static void enableTracing() {
sTracingEnabled = true;
- };
+ }
/**
* Disable Binder IPC tracing.
*
* @hide
*/
- public static void disableTracing() {
+ public static void disableTracing() {
sTracingEnabled = false;
}
@@ -128,6 +127,59 @@ public class Binder implements IBinder {
return sTransactionTracker;
}
+ /** {@hide} */
+ static volatile boolean sWarnOnBlocking = false;
+
+ /**
+ * Warn if any blocking binder transactions are made out from this process.
+ * This is typically only useful for the system process, to prevent it from
+ * blocking on calls to external untrusted code. Instead, all outgoing calls
+ * that require a result must be sent as {@link IBinder#FLAG_ONEWAY} calls
+ * which deliver results through a callback interface.
+ *
+ * @hide
+ */
+ public static void setWarnOnBlocking(boolean warnOnBlocking) {
+ sWarnOnBlocking = warnOnBlocking;
+ }
+
+ /**
+ * Allow blocking calls on the given interface, overriding the requested
+ * value of {@link #setWarnOnBlocking(boolean)}.
+ * <p>
+ * This should only be rarely called when you are <em>absolutely sure</em>
+ * the remote interface is a built-in system component that can never be
+ * upgraded. In particular, this <em>must never</em> be called for
+ * interfaces hosted by package that could be upgraded or replaced,
+ * otherwise you risk system instability if that remote interface wedges.
+ *
+ * @hide
+ */
+ public static IBinder allowBlocking(IBinder binder) {
+ try {
+ if (binder instanceof BinderProxy) {
+ ((BinderProxy) binder).mWarnOnBlocking = false;
+ } else if (binder != null
+ && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
+ Log.w(TAG, "Unable to allow blocking on interface " + binder);
+ }
+ } catch (RemoteException ignored) {
+ }
+ return binder;
+ }
+
+ /**
+ * Inherit the current {@link #allowBlocking(IBinder)} value from one given
+ * interface to another.
+ *
+ * @hide
+ */
+ public static void copyAllowBlocking(IBinder fromBinder, IBinder toBinder) {
+ if (fromBinder instanceof BinderProxy && toBinder instanceof BinderProxy) {
+ ((BinderProxy) toBinder).mWarnOnBlocking = ((BinderProxy) fromBinder).mWarnOnBlocking;
+ }
+ }
+
/* mObject is used by native code, do not remove or rename */
private long mObject;
private IInterface mOwner;
@@ -322,9 +374,7 @@ public class Binder implements IBinder {
* re-enabled.
*/
public static void setDumpDisabled(String msg) {
- synchronized (Binder.class) {
- sDumpDisabled = msg;
- }
+ sDumpDisabled = msg;
}
/**
@@ -400,10 +450,7 @@ public class Binder implements IBinder {
}
void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
- final String disabled;
- synchronized (Binder.class) {
- disabled = sDumpDisabled;
- }
+ final String disabled = sDumpDisabled;
if (disabled == null) {
try {
dump(fd, pw, args);
@@ -612,6 +659,9 @@ public class Binder implements IBinder {
}
final class BinderProxy implements IBinder {
+ // Assume the process-wide default value when created
+ volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking;
+
public native boolean pingBinder();
public native boolean isBinderAlive();
@@ -621,6 +671,15 @@ final class BinderProxy implements IBinder {
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
+
+ if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
+ // For now, avoid spamming the log by disabling after we've logged
+ // about this interface at least once
+ mWarnOnBlocking = false;
+ Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
+ new Throwable());
+ }
+
final boolean tracingEnabled = Binder.isTracingEnabled();
if (tracingEnabled) {
final Throwable tr = new Throwable();
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index 640105ce8f98..e11494d5cd41 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -36,7 +36,8 @@ public final class ServiceManager {
}
// Find the service manager
- sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
+ sServiceManager = ServiceManagerNative
+ .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
@@ -52,7 +53,7 @@ public final class ServiceManager {
if (service != null) {
return service;
} else {
- return getIServiceManager().getService(name);
+ return Binder.allowBlocking(getIServiceManager().getService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
@@ -117,7 +118,7 @@ public final class ServiceManager {
if (service != null) {
return service;
} else {
- return getIServiceManager().checkService(name);
+ return Binder.allowBlocking(getIServiceManager().checkService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in checkService", e);
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index b826584009c1..a280e594525e 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -41,6 +41,8 @@ public final class Downloads {
public static final class Impl implements BaseColumns {
private Impl() {}
+ public static final String AUTHORITY = "downloads";
+
/**
* The permission to access the download manager
*/
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 4fc789249c5c..5e59a64b23d4 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
+import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
@@ -630,7 +631,7 @@ public final class KeyChain {
if (!mConnectedAtLeastOnce) {
mConnectedAtLeastOnce = true;
try {
- q.put(IKeyChainService.Stub.asInterface(service));
+ q.put(IKeyChainService.Stub.asInterface(Binder.allowBlocking(service)));
} catch (InterruptedException e) {
// will never happen, since the queue starts with one available slot
}
diff --git a/location/java/android/location/IGeofenceProvider.aidl b/location/java/android/location/IGeofenceProvider.aidl
index 5a5fdc635b00..d4ff0dd70bf2 100644
--- a/location/java/android/location/IGeofenceProvider.aidl
+++ b/location/java/android/location/IGeofenceProvider.aidl
@@ -23,6 +23,6 @@ import android.hardware.location.IGeofenceHardware;
*
* {@hide}
*/
-interface IGeofenceProvider {
+oneway interface IGeofenceProvider {
void setGeofenceHardware(in IGeofenceHardware proxy);
}
diff --git a/media/java/android/media/IRingtonePlayer.aidl b/media/java/android/media/IRingtonePlayer.aidl
index 4b1e39f2fc9d..5f6686a88a7e 100644
--- a/media/java/android/media/IRingtonePlayer.aidl
+++ b/media/java/android/media/IRingtonePlayer.aidl
@@ -26,14 +26,14 @@ import android.os.UserHandle;
*/
interface IRingtonePlayer {
/** Used for Ringtone.java playback */
- void play(IBinder token, in Uri uri, in AudioAttributes aa, float volume, boolean looping);
- void stop(IBinder token);
+ oneway void play(IBinder token, in Uri uri, in AudioAttributes aa, float volume, boolean looping);
+ oneway void stop(IBinder token);
boolean isPlaying(IBinder token);
- void setPlaybackProperties(IBinder token, float volume, boolean looping);
+ oneway void setPlaybackProperties(IBinder token, float volume, boolean looping);
/** Used for Notification sound playback. */
- void playAsync(in Uri uri, in UserHandle user, boolean looping, in AudioAttributes aa);
- void stopAsync();
+ oneway void playAsync(in Uri uri, in UserHandle user, boolean looping, in AudioAttributes aa);
+ oneway void stopAsync();
/** Return the title of the media. */
String getTitle(in Uri uri);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 645604848580..9b3fac3d66d4 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1364,7 +1364,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
try {
mBluetoothLock.writeLock().lock();
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
- mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service);
+ mBluetoothGatt = IBluetoothGatt.Stub
+ .asInterface(Binder.allowBlocking(service));
onBluetoothGattServiceUp();
break;
} // else must be SERVICE_IBLUETOOTH
@@ -1374,7 +1375,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mBinding = false;
mBluetoothBinder = service;
- mBluetooth = IBluetooth.Stub.asInterface(service);
+ mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
if (!isNameAndAddressSet()) {
Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 33f92344f615..0414b47e0604 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -92,7 +92,7 @@ public class MmsServiceBroker extends SystemService {
public void onServiceConnected(ComponentName name, IBinder service) {
Slog.i(TAG, "MmsService connected");
synchronized (MmsServiceBroker.this) {
- mService = IMms.Stub.asInterface(service);
+ mService = IMms.Stub.asInterface(Binder.allowBlocking(service));
MmsServiceBroker.this.notifyAll();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2d6832d32af5..db5a388ca9bc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2714,7 +2714,8 @@ public class ActivityManagerService extends IActivityManager.Stub
for (int i=0; i<N; i++) {
Parcel data2 = Parcel.obtain();
try {
- procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
+ procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
+ Binder.FLAG_ONEWAY);
} catch (RemoteException e) {
}
data2.recycle();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ca773357c772..57afabe89dfa 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1079,8 +1079,8 @@ public class PackageManagerService extends IPackageManager.Stub {
class DefaultContainerConnection implements ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
- IMediaContainerService imcs =
- IMediaContainerService.Stub.asInterface(service);
+ final IMediaContainerService imcs = IMediaContainerService.Stub
+ .asInterface(Binder.allowBlocking(service));
mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
}
@@ -16615,7 +16615,8 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (this) {
- mContainerService = IMediaContainerService.Stub.asInterface(service);
+ mContainerService = IMediaContainerService.Stub
+ .asInterface(Binder.allowBlocking(service));
notifyAll();
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index cc96f565564a..6614fe3a31e3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -27,6 +27,7 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
import android.os.BaseBundle;
+import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.FactoryTest;
@@ -267,6 +268,9 @@ public final class SystemServer {
SystemProperties.set("persist.sys.localevar", "");
}
+ // The system server should never make non-oneway calls
+ Binder.setWarnOnBlocking(true);
+
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());