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

Commit 560c3ac1 authored by markchien's avatar markchien
Browse files

Passing caller package name to setBluetoothTethering

This is necessary to examine caller's permission. If caller's uid is not
same as passing package name, SecurityException would be throwed.
This change also clear the identity before calling
BluetoothPan#setBluetoothTethering() in Tethering#setBluetoothTethering.
This is fine because caller already pass permission check before in
ConnectivityService. See the flow below:
ConnectivityManager#startTethering -> ConnectivityService#startTethering
-> Tethering#startTethering -> Tethering#setBluetoothTethering
-> BluetoothPan#setBluetoothTethering

Bug: 134649258
Test: -build, flash, boot
      -atest FrameworkNetTests
      -manual test with bluetooth OFF/ON

Change-Id: I2140398ad3bbc8076f729c843f0515c654553aaf
parent d889cb50
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -118,6 +118,8 @@ public final class BluetoothPan implements BluetoothProfile {
     */
    public static final int PAN_OPERATION_SUCCESS = 1004;

    private final Context mContext;

    private BluetoothAdapter mAdapter;
    private final BluetoothProfileConnector<IBluetoothPan> mProfileConnector =
            new BluetoothProfileConnector(this, BluetoothProfile.PAN,
@@ -136,6 +138,7 @@ public final class BluetoothPan implements BluetoothProfile {
    @UnsupportedAppUsage
    /*package*/ BluetoothPan(Context context, ServiceListener listener) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mContext = context;
        mProfileConnector.connect(context, listener);
    }

@@ -287,11 +290,12 @@ public final class BluetoothPan implements BluetoothProfile {

    @UnsupportedAppUsage
    public void setBluetoothTethering(boolean value) {
        if (DBG) log("setBluetoothTethering(" + value + ")");
        String pkgName = mContext.getOpPackageName();
        if (DBG) log("setBluetoothTethering(" + value + "), calling package:" + pkgName);
        final IBluetoothPan service = getService();
        if (service != null && isEnabled()) {
            try {
                service.setBluetoothTethering(value);
                service.setBluetoothTethering(value, pkgName);
            } catch (RemoteException e) {
                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            }
+14 −1
Original line number Diff line number Diff line
@@ -455,7 +455,20 @@ public class Tethering extends BaseNetworkObserver {

            @Override
            public void onServiceConnected(int profile, BluetoothProfile proxy) {
                // Clear identify is fine because caller already pass tethering permission at
                // ConnectivityService#startTethering()(or stopTethering) before the control comes
                // here. Bluetooth will check tethering permission again that there is
                // Context#getOpPackageName() under BluetoothPan#setBluetoothTethering() to get
                // caller's package name for permission check.
                // Calling BluetoothPan#setBluetoothTethering() here means the package name always
                // be system server. If calling identity is not cleared, that package's uid might
                // not match calling uid and end up in permission denied.
                final long identityToken = Binder.clearCallingIdentity();
                try {
                    ((BluetoothPan) proxy).setBluetoothTethering(enable);
                } finally {
                    Binder.restoreCallingIdentity(identityToken);
                }
                // TODO: Enabling bluetooth tethering can fail asynchronously here.
                // We should figure out a way to bubble up that failure instead of sending success.
                final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)