diff options
28 files changed, 535 insertions, 78 deletions
diff --git a/android/app/res/values-af/strings.xml b/android/app/res/values-af/strings.xml index 6640182e24..1351675302 100644 --- a/android/app/res/values-af/strings.xml +++ b/android/app/res/values-af/strings.xml @@ -18,9 +18,9 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_name" msgid="2326164424236203271">"Bluetooth"</string> <string name="permlab_bluetoothShareManager" msgid="5297865456717871041">"Maak toegang aflaaibestuurder oop."</string> - <string name="permdesc_bluetoothShareManager" msgid="1588034776955941477">"Gee aan die program toegang tot die BluetoothShare-bestuurder en om dit te gebruik om lêers oor te dra."</string> + <string name="permdesc_bluetoothShareManager" msgid="1588034776955941477">"Gee aan die app toegang tot die BluetoothShare-bestuurder en om dit te gebruik om lêers oor te dra."</string> <string name="permlab_bluetoothAcceptlist" msgid="5785922051395856524">"Voeg Bluetooth-toesteltoegang by aanvaarlys."</string> - <string name="permdesc_bluetoothAcceptlist" msgid="259308920158011885">"Laat die program toe om \'n Bluetooth-toestel tydelik by aanvaarlys te voeg, sodat daardie toestel lêers na hierdie toestel kan stuur sonder die gebruiker se bevestiging."</string> + <string name="permdesc_bluetoothAcceptlist" msgid="259308920158011885">"Laat die app toe om \'n Bluetooth-toestel tydelik by aanvaarlys te voeg, sodat daardie toestel lêers na hierdie toestel kan stuur sonder die gebruiker se bevestiging."</string> <string name="bt_share_picker_label" msgid="7464438494743777696">"Bluetooth"</string> <string name="unknown_device" msgid="2317679521750821654">"Onbekende toestel"</string> <string name="unknownNumber" msgid="1245183329830158661">"Onbekend"</string> @@ -71,7 +71,7 @@ <string name="upload_fail_cancel" msgid="1632528037932779727">"Maak toe"</string> <string name="bt_error_btn_ok" msgid="2802751202009957372">"OK"</string> <string name="unknown_file" msgid="3719981572107052685">"Onbekende lêer"</string> - <string name="unknown_file_desc" msgid="9185609398960437760">"Daar is geen program om hierdie tipe lêer te hanteer nie. \n"</string> + <string name="unknown_file_desc" msgid="9185609398960437760">"Daar is geen app om hierdie tipe lêer te hanteer nie. \n"</string> <string name="not_exist_file" msgid="5097565588949092486">"Geen lêers nie"</string> <string name="not_exist_file_desc" msgid="250802392160941265">"Die lêer bestaan nie. \n"</string> <string name="enabling_progress_title" msgid="5262637688863903594">"Wag asseblief…"</string> diff --git a/android/app/res/values-bs/strings.xml b/android/app/res/values-bs/strings.xml index cd9f65c929..c446c1be27 100644 --- a/android/app/res/values-bs/strings.xml +++ b/android/app/res/values-bs/strings.xml @@ -115,7 +115,7 @@ <string name="bluetooth_a2dp_sink_queue_name" msgid="7521243473328258997">"Trenutno se reproducira"</string> <string name="bluetooth_map_settings_app_icon" msgid="3501432663809664982">"Ikona aplikacije"</string> <string name="bluetooth_disconnected" msgid="6841396291728343534">"Bluetooth audio je isključen"</string> - <string name="a2dp_sink_mbs_label" msgid="6035366346569127155">"Bluetooth Audio"</string> + <string name="a2dp_sink_mbs_label" msgid="6035366346569127155">"Bluetooth zvuk"</string> <string name="bluetooth_opp_file_limit_exceeded" msgid="6612109860149473930">"Nije moguće prenijeti fajlove veće od 4 GB"</string> <string name="bluetooth_connect_action" msgid="2319449093046720209">"Poveži se s Bluetoothom"</string> <string name="bluetooth_enabled_apm_title" msgid="6914461147844949044">"Bluetooth je uključen u načinu rada u avionu"</string> diff --git a/android/app/res/values-gu/strings.xml b/android/app/res/values-gu/strings.xml index bae6c11943..a72b635790 100644 --- a/android/app/res/values-gu/strings.xml +++ b/android/app/res/values-gu/strings.xml @@ -115,7 +115,7 @@ <string name="bluetooth_a2dp_sink_queue_name" msgid="7521243473328258997">"હમણાં વાગી રહ્યું છે"</string> <string name="bluetooth_map_settings_app_icon" msgid="3501432663809664982">"ઍપ્લિકેશન આયકન"</string> <string name="bluetooth_disconnected" msgid="6841396291728343534">"બ્લૂટૂથ ઑડિઓ ડિસ્કનેક્ટ થયું"</string> - <string name="a2dp_sink_mbs_label" msgid="6035366346569127155">"બ્લૂટૂથ ઑડિઓ"</string> + <string name="a2dp_sink_mbs_label" msgid="6035366346569127155">"બ્લૂટૂથ ઑડિયો"</string> <string name="bluetooth_opp_file_limit_exceeded" msgid="6612109860149473930">"4GB કરતા મોટી ફાઇલ ટ્રાન્સફર કરી શકાતી નથી"</string> <string name="bluetooth_connect_action" msgid="2319449093046720209">"બ્લૂટૂથ સાથે કનેક્ટ કરો"</string> <string name="bluetooth_enabled_apm_title" msgid="6914461147844949044">"એરપ્લેન મોડમાં બ્લૂટૂથ ચાલુ છે"</string> diff --git a/android/app/res/values-hr/strings.xml b/android/app/res/values-hr/strings.xml index 0931f34d13..244cda77cb 100644 --- a/android/app/res/values-hr/strings.xml +++ b/android/app/res/values-hr/strings.xml @@ -115,7 +115,7 @@ <string name="bluetooth_a2dp_sink_queue_name" msgid="7521243473328258997">"Upravo svira"</string> <string name="bluetooth_map_settings_app_icon" msgid="3501432663809664982">"Ikona aplikacije"</string> <string name="bluetooth_disconnected" msgid="6841396291728343534">"Veza Bluetooth Audija prekinuta"</string> - <string name="a2dp_sink_mbs_label" msgid="6035366346569127155">"Bluetooth Audio"</string> + <string name="a2dp_sink_mbs_label" msgid="6035366346569127155">"Bluetooth zvuk"</string> <string name="bluetooth_opp_file_limit_exceeded" msgid="6612109860149473930">"Datoteke veće od 4 GB ne mogu se prenijeti"</string> <string name="bluetooth_connect_action" msgid="2319449093046720209">"Povezivanje s Bluetoothom"</string> <string name="bluetooth_enabled_apm_title" msgid="6914461147844949044">"Bluetooth je uključen u načinu rada u zrakoplovu"</string> diff --git a/android/app/res/values-kn/strings_pbap.xml b/android/app/res/values-kn/strings_pbap.xml index 93543c990a..dee248c4e5 100644 --- a/android/app/res/values-kn/strings_pbap.xml +++ b/android/app/res/values-kn/strings_pbap.xml @@ -4,7 +4,7 @@ <string name="pbap_session_key_dialog_title" msgid="5103201901254778256">"%1$s ಗಾಗಿ ಸೆಶನ್ ಕೀ ಟೈಪ್ ಮಾಡಿ"</string> <string name="pbap_session_key_dialog_header" msgid="5073165544713355581">"ಬ್ಲೂಟೂತ್ ಸೆಶನ್ ಕೀ ಅಗತ್ಯವಿದೆ"</string> <string name="pbap_acceptance_timeout_message" msgid="3071798915563151284">"%1$s ರೊಂದಿಗೆ ಸಂಪರ್ಕವನ್ನು ಸ್ವೀಕರಿಸುವಲ್ಲಿ ಸಮಯ ಮುಕ್ತಾಯಗೊಂಡಿದೆ"</string> - <string name="pbap_authentication_timeout_message" msgid="2089914949828656737">"%1$s ರೊಂದಿಗೆ ಸೆಶನ್ ಕೀಯನ್ನು ಇನ್ಪುಟ್ ಮಾಡುವಲ್ಲಿ ಸಮಯ ಮುಕ್ತಾಯಗೊಂಡಿದೆ"</string> + <string name="pbap_authentication_timeout_message" msgid="2089914949828656737">"%1$s ರೊಂದಿಗೆ ಸೆಶನ್ ಕೀಯನ್ನು ಇನ್ಪುಟ್ ಮಾಡುವಾಗ ಸಮಯ ಮುಕ್ತಾಯಗೊಂಡಿದೆ"</string> <string name="auth_notif_ticker" msgid="7344125635314034621">"Obex ದೃಢೀಕರಣ ವಿನಂತಿ"</string> <string name="auth_notif_title" msgid="6639277119990416473">"ಸೆಶನ್ ಕೀ"</string> <string name="auth_notif_message" msgid="7044369885874418693">"%1$s ಗಾಗಿ ಸೆಶನ್ ಕೀ ಟೈಪ್ ಮಾಡಿ"</string> diff --git a/android/app/res/values-sq/strings.xml b/android/app/res/values-sq/strings.xml index 5b2d8f1fcf..e23003f021 100644 --- a/android/app/res/values-sq/strings.xml +++ b/android/app/res/values-sq/strings.xml @@ -114,8 +114,8 @@ <string name="transfer_clear_dlg_title" msgid="128904516163257225">"Pastro"</string> <string name="bluetooth_a2dp_sink_queue_name" msgid="7521243473328258997">"Po luhet tani"</string> <string name="bluetooth_map_settings_app_icon" msgid="3501432663809664982">"Ikona e aplikacionit"</string> - <string name="bluetooth_disconnected" msgid="6841396291728343534">"Audioja e Bluetooth-it e shkëputur"</string> - <string name="a2dp_sink_mbs_label" msgid="6035366346569127155">"Audioja e Bluetooth-it"</string> + <string name="bluetooth_disconnected" msgid="6841396291728343534">"Audioja me Bluetooth e shkëputur"</string> + <string name="a2dp_sink_mbs_label" msgid="6035366346569127155">"Audioja me Bluetooth"</string> <string name="bluetooth_opp_file_limit_exceeded" msgid="6612109860149473930">"Skedarët më të mëdhenj se 4 GB nuk mund të transferohen"</string> <string name="bluetooth_connect_action" msgid="2319449093046720209">"Lidhu me Bluetooth"</string> <string name="bluetooth_enabled_apm_title" msgid="6914461147844949044">"Bluetooth-i aktiv në modalitetin e aeroplanit"</string> diff --git a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java index e73c4f99ba..fe2aaa2be2 100644 --- a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java +++ b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java @@ -18,6 +18,7 @@ package com.android.bluetooth; import android.annotation.NonNull; import android.annotation.SuppressLint; +import android.app.ComponentCaller; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.PeriodicAdvertisingCallback; @@ -33,6 +34,7 @@ import android.database.Cursor; import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Handler; @@ -43,6 +45,8 @@ import android.os.ParcelFileDescriptor; import android.provider.Telephony; import android.util.Log; +import androidx.annotation.RequiresApi; + import com.android.bluetooth.bass_client.BassClientPeriodicAdvertisingManager; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.HeaderSet; @@ -294,4 +298,11 @@ public class BluetoothMethodProxy { MediaSessionManager manager) { return manager.getActiveSessions(null); } + + /** Proxies {@link ComponentCaller#checkContentUriPermission(Uri, int)}. } */ + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + public int componentCallerCheckContentUriPermission( + ComponentCaller caller, Uri uri, int modeFlags) { + return caller.checkContentUriPermission(uri, modeFlags); + } } diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index fe9cca3409..6bba10f0da 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -27,6 +27,7 @@ import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE; import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE; import static android.bluetooth.BluetoothDevice.BATTERY_LEVEL_UNKNOWN; +import static android.bluetooth.BluetoothDevice.BOND_NONE; import static android.bluetooth.BluetoothDevice.TRANSPORT_AUTO; import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; @@ -6321,6 +6322,13 @@ public class AdapterService extends Service { mCsipSetCoordinatorService.handleBondStateChanged(device, fromState, toState); } mDatabaseManager.handleBondStateChanged(device, fromState, toState); + + if (toState == BOND_NONE) { + // Remove the permissions for unbonded devices + setMessageAccessPermission(device, BluetoothDevice.ACCESS_UNKNOWN); + setPhonebookAccessPermission(device, BluetoothDevice.ACCESS_UNKNOWN); + setSimAccessPermission(device, BluetoothDevice.ACCESS_UNKNOWN); + } } static int convertScanModeToHal(int mode) { diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java index 002ac61e97..216c0f3506 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java @@ -34,6 +34,9 @@ package com.android.bluetooth.opp; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; +import static java.util.function.Predicate.not; +import static java.util.stream.Collectors.toList; + import android.annotation.SuppressLint; import android.app.Activity; import android.bluetooth.BluetoothDevicePicker; @@ -42,25 +45,32 @@ import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.provider.Settings; import android.util.Log; import android.util.Patterns; import android.widget.Toast; +import androidx.annotation.RequiresApi; + import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; import com.android.bluetooth.Utils; import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; +import com.android.modules.utils.build.SdkLevel; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -124,6 +134,16 @@ public class BluetoothOppLauncherActivity extends Activity { // Browser, share one link goes to this case; if (stream != null && type != null) { Log.v(TAG, "Get ACTION_SEND intent: Uri = " + stream + "; mimetype = " + type); + if (Flags.oppCheckContentUriPermissions() && SdkLevel.isAtLeastV()) { + if (!checkCallerAndSelfContentUriPermission(stream)) { + finish(); + return; + } else { + Log.v(TAG, "Sender has permissions to access Uri = " + stream); + } + } else { + Log.v(TAG, "Did not check sender permissions to Uri = " + stream); + } // Save type/stream, will be used when adding transfer // session to DB. Thread t = @@ -191,6 +211,7 @@ public class BluetoothOppLauncherActivity extends Activity { } else if (action.equals(Intent.ACTION_SEND_MULTIPLE)) { final String mimeType = intent.getType(); final ArrayList<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + final List<Uri> permittedUris; if (mimeType != null && uris != null) { Log.v( TAG, @@ -198,6 +219,37 @@ public class BluetoothOppLauncherActivity extends Activity { + uris + "\n Type= " + mimeType); + if (Flags.oppCheckContentUriPermissions() && SdkLevel.isAtLeastV()) { + permittedUris = + uris.stream() + .filter(this::checkCallerAndSelfContentUriPermission) + .collect(toList()); + if (permittedUris.isEmpty()) { + Log.w(TAG, "Sender has no permissions to access any uris in " + uris); + finish(); + return; + } else if (!permittedUris.equals(uris)) { + List<Uri> blockedUris = + uris.stream() + .filter(not(permittedUris::contains)) + .collect(toList()); + Log.w( + TAG, + "Sender has partial permissions to uris. " + + "Permitted uris: " + + permittedUris + + ", " + + "Blocked uris: " + + blockedUris + + ". " + + "Proceeding only with permitted uris."); + } else { + Log.v(TAG, "Sender has permissions to all uris in " + uris); + } + } else { + permittedUris = uris; + Log.v(TAG, "Did not check sender permissions to uris in " + uris); + } Thread t = new Thread( new Runnable() { @@ -208,7 +260,7 @@ public class BluetoothOppLauncherActivity extends Activity { BluetoothOppLauncherActivity.this) .saveSendingFileInfo( mimeType, - uris, + permittedUris, false /* isHandover */, true /* fromExternal */); // Done getting file info..Launch device picker @@ -291,6 +343,33 @@ public class BluetoothOppLauncherActivity extends Activity { } } + /** + * Checks whether the sender (and Bluetooth) have permissions to access the given content uri. + * The result does not differentiate the sender vs. Bluetooth's lack of permissions. + * + * @param uri A uri with a <tt>content</tt> scheme. + * @return true if both the sender and Bluetooth have permissions, false otherwise. + */ + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + private boolean checkCallerAndSelfContentUriPermission(Uri uri) { + boolean hasPermission = false; + try { + hasPermission = + BluetoothMethodProxy.getInstance() + .componentCallerCheckContentUriPermission( + getInitialCaller(), + uri, + Intent.FLAG_GRANT_READ_URI_PERMISSION) + == PackageManager.PERMISSION_GRANTED; + } catch (SecurityException e) { + Log.w(TAG, "Bluetooth does not have permissions to Uri = " + uri, e); + } + if (!hasPermission) { + Log.w(TAG, "Sender does not have permissions to Uri = " + uri); + } + return hasPermission; + } + /* Returns true if Bluetooth is allowed given current airplane mode settings. */ private boolean isBluetoothAllowed() { final ContentResolver resolver = this.getContentResolver(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java index c162cc9562..bceff44b7a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java @@ -23,9 +23,14 @@ import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -33,7 +38,11 @@ import android.bluetooth.BluetoothDevicePicker; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.sysprop.BluetoothProperties; import androidx.lifecycle.Lifecycle; @@ -45,9 +54,9 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.flags.Flags; import org.junit.After; -import org.junit.Assume; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; @@ -59,15 +68,20 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; @MediumTest @RunWith(AndroidJUnit4.class) public class BluetoothOppLauncherActivityTest { + public static final String CONTENT_TYPE = "image/png"; + Context mTargetContext; Intent mIntent; BluetoothMethodProxy mMethodProxy; - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); @Mock BluetoothOppManager mBluetoothOppManager; @@ -76,9 +90,11 @@ public class BluetoothOppLauncherActivityTest { // Add retry rule to resolve this problem. @Rule public TestUtils.RetryTestRule mRetryTestRule = new TestUtils.RetryTestRule(); + @Rule public SetFlagsRule.ClassRule mSetFlagsClassRule = new SetFlagsRule.ClassRule(); + @Before public void setUp() throws Exception { - Assume.assumeTrue(BluetoothProperties.isProfileOppEnabled().orElse(false)); + assumeTrue(BluetoothProperties.isProfileOppEnabled().orElse(false)); mTargetContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); mMethodProxy = spy(BluetoothMethodProxy.getInstance()); @@ -129,6 +145,229 @@ public class BluetoothOppLauncherActivityTest { } @Test + @EnableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSend_checkEnabled_noPermission_doesNotSaveFileInfo() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_DENIED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + String uriString = "content://test.provider/1"; + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendIntent(uriString)); + + verify(mBluetoothOppManager, never()) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriString), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + @Test + @EnableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSend_checkEnabled_hasPermission_savesFileInfo() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_GRANTED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + String uriString = "content://test.provider/1"; + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendIntent(uriString)); + + verify(mBluetoothOppManager) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriString), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + @Test + @DisableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSend_checkNotEnabled_noPermission_savesFileInfo() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_DENIED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + String uriString = "content://test.provider/1"; + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendIntent(uriString)); + + verify(mBluetoothOppManager) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriString), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + @Test + @DisableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSend_checkNotEnabled_hasPermission_savesFileInfo() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_GRANTED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + String uriString = "content://test.provider/1"; + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendIntent(uriString)); + + verify(mBluetoothOppManager) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriString), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + private Intent createSendIntent(String uriString) { + return new Intent(Intent.ACTION_SEND) + .setClass(mTargetContext, BluetoothOppLauncherActivity.class) + .setType(CONTENT_TYPE) + .putExtra(Intent.EXTRA_STREAM, Uri.parse(uriString)); + } + + @Test + @EnableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSendMultiple_checkEnabled_noPermission_doesNotSaveFileInfos() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_DENIED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + List<Uri> uriList = + Arrays.asList( + Uri.parse("content://test.provider/1"), + Uri.parse("content://test.provider/2")); + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendMultipleIntent(uriList)); + + verify(mBluetoothOppManager, never()) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriList), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + @Test + @EnableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSendMultiple_checkEnabled_hasPermission_savesFileInfos() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_GRANTED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + List<Uri> uriList = + Arrays.asList( + Uri.parse("content://test.provider/1"), + Uri.parse("content://test.provider/2")); + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendMultipleIntent(uriList)); + + verify(mBluetoothOppManager) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriList), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + @Test + @EnableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void + onCreate_withActionSendMultiple_checkEnabled_partialPermission_savesPermittedFileInfo() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_GRANTED, PackageManager.PERMISSION_DENIED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + List<Uri> uriList = + Arrays.asList( + Uri.parse("content://test.provider/1"), + Uri.parse("content://test.provider/2")); + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendMultipleIntent(uriList)); + + verify(mBluetoothOppManager) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(Arrays.asList(Uri.parse("content://test.provider/1"))), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + @Test + @DisableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSendMultiple_checkNotEnabled_noPermission_savesFileInfos() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_DENIED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + List<Uri> uriList = + Arrays.asList( + Uri.parse("content://test.provider/1"), + Uri.parse("content://test.provider/2")); + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendMultipleIntent(uriList)); + + verify(mBluetoothOppManager) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriList), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + @Test + @DisableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSendMultiple_checkNotEnabled_hasPermission_savesFileInfos() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_GRANTED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + List<Uri> uriList = + Arrays.asList( + Uri.parse("content://test.provider/1"), + Uri.parse("content://test.provider/2")); + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendMultipleIntent(uriList)); + + verify(mBluetoothOppManager) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriList), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + @Test + @DisableFlags(Flags.FLAG_OPP_CHECK_CONTENT_URI_PERMISSIONS) + public void onCreate_withActionSendMultiple_checkNotEnabled_partialPermission_savesFileInfos() + throws Exception { + doReturn(true).when(mMethodProxy).bluetoothAdapterIsEnabled(any()); + doReturn(PackageManager.PERMISSION_GRANTED, PackageManager.PERMISSION_DENIED) + .when(mMethodProxy) + .componentCallerCheckContentUriPermission(any(), any(), anyInt()); + List<Uri> uriList = + Arrays.asList( + Uri.parse("content://test.provider/1"), + Uri.parse("content://test.provider/2")); + + ActivityScenario<BluetoothOppLauncherActivity> unused = + ActivityScenario.launch(createSendMultipleIntent(uriList)); + + verify(mBluetoothOppManager) + .saveSendingFileInfo( + eq(CONTENT_TYPE), eq(uriList), + anyBoolean() /* isHandover */, anyBoolean() /* fromExternal */); + } + + private Intent createSendMultipleIntent(List<Uri> uriList) { + return new Intent(Intent.ACTION_SEND_MULTIPLE) + .setClass(mTargetContext, BluetoothOppLauncherActivity.class) + .setType(CONTENT_TYPE) + .putParcelableArrayListExtra(Intent.EXTRA_STREAM, new ArrayList<>(uriList)); + } + + @Test public void onCreate_withActionOpen_sendBroadcast() throws Exception { mIntent.setAction(Constants.ACTION_OPEN); mIntent.setData(Uri.EMPTY); diff --git a/flags/security.aconfig b/flags/security.aconfig index ddfd78611c..dc6fea1ac5 100644 --- a/flags/security.aconfig +++ b/flags/security.aconfig @@ -44,3 +44,84 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "btsec_avdt_msg_ind_type_confusion" + namespace: "bluetooth" + description: "Properly check current state and sig value of avdt rej/rsp messages before parsing" + bug: "358212054" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "btsec_cycle_irks" + namespace: "bluetooth" + description: "Change the IRK per BT spec when all devices are unbonded" + bug: "372714979" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "btsec_le_oob_pairing" + namespace: "bluetooth" + description: "Drop connection if a peer claims it has OOB data but no local OOB data is stored" + bug: "374376990" + metadata { + purpose: PURPOSE_BUGFIX + } +} + + +flag { + name: "opp_check_content_uri_permissions" + namespace: "bluetooth" + description: "Check that the launching application for OPP has read access to the given content URI, on Android V+" + bug: "375466974" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "sec_disconnect_on_le_key_missing" + namespace: "bluetooth" + description: "Disconnect LE link when keys are missing during encryption" + bug: "376680866" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "guard_bonded_device_properties" + namespace: "bluetooth" + description: "Don't update device properties for bonded devices from the device discovery results" + bug: "376928594" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "disconnect_on_encryption_failure" + namespace: "bluetooth" + description: "Disconnect ACL link when encryption fails" + bug: "378764380" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "upgrade_temp_bonding_on_auth_req" + namespace: "bluetooth" + description: "Upgrade security If it is on temp bonding & authentication is requirement" + bug: "385747513" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfigMetadata.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfigMetadata.java index c48ca4c842..7beb1da111 100644 --- a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfigMetadata.java +++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfigMetadata.java @@ -227,12 +227,7 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable { @Override public void writeToParcel(Parcel out, int flags) { out.writeLong(mAudioLocation); - if (mRawMetadata != null) { - out.writeInt(mRawMetadata.length); - out.writeByteArray(mRawMetadata); - } else { - out.writeInt(-1); - } + out.writeByteArray(mRawMetadata); out.writeInt(mSampleRate); out.writeInt(mFrameDuration); out.writeInt(mOctetsPerFrame); @@ -250,12 +245,8 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable { public @NonNull BluetoothLeAudioCodecConfigMetadata createFromParcel( @NonNull Parcel in) { long audioLocation = in.readLong(); - int rawMetadataLen = in.readInt(); - byte[] rawMetadata; - if (rawMetadataLen != -1) { - rawMetadata = new byte[rawMetadataLen]; - in.readByteArray(rawMetadata); - } else { + byte[] rawMetadata = in.createByteArray(); + if (rawMetadata == null) { rawMetadata = new byte[0]; } int sampleRate = in.readInt(); diff --git a/framework/java/android/bluetooth/BluetoothLeAudioContentMetadata.java b/framework/java/android/bluetooth/BluetoothLeAudioContentMetadata.java index 89ea28267a..3a032a7bb2 100644 --- a/framework/java/android/bluetooth/BluetoothLeAudioContentMetadata.java +++ b/framework/java/android/bluetooth/BluetoothLeAudioContentMetadata.java @@ -132,7 +132,6 @@ public final class BluetoothLeAudioContentMetadata implements Parcelable { public void writeToParcel(Parcel out, int flags) { BluetoothUtils.writeStringToParcel(out, mProgramInfo); BluetoothUtils.writeStringToParcel(out, mLanguage); - out.writeInt(mRawMetadata.length); out.writeByteArray(mRawMetadata); } @@ -148,9 +147,7 @@ public final class BluetoothLeAudioContentMetadata implements Parcelable { @NonNull Parcel in) { final String programInfo = in.readString(); final String language = in.readString(); - final int rawMetadataLength = in.readInt(); - byte[] rawMetadata = new byte[rawMetadataLength]; - in.readByteArray(rawMetadata); + byte[] rawMetadata = in.createByteArray(); return new BluetoothLeAudioContentMetadata(programInfo, language, rawMetadata); } diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java b/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java index 27d594216a..bfa6741a99 100644 --- a/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java +++ b/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java @@ -489,14 +489,7 @@ public final class BluetoothLeBroadcastReceiveState implements Parcelable { out.writeInt(mBroadcastId); out.writeInt(mPaSyncState); out.writeInt(mBigEncryptionState); - - if (mBadCode != null) { - out.writeInt(mBadCode.length); - out.writeByteArray(mBadCode); - } else { - // -1 indicates that there is no "bad broadcast code" - out.writeInt(-1); - } + out.writeByteArray(mBadCode); out.writeInt(mNumSubgroups); out.writeList(mBisSyncState); out.writeTypedList(mSubgroupMetadata); @@ -557,15 +550,7 @@ public final class BluetoothLeBroadcastReceiveState implements Parcelable { final int broadcastId = in.readInt(); final int paSyncState = in.readInt(); final int bigEncryptionState = in.readInt(); - final int badCodeLen = in.readInt(); - byte[] badCode = null; - - if (badCodeLen != -1) { - badCode = new byte[badCodeLen]; - if (badCodeLen > 0) { - in.readByteArray(badCode); - } - } + final byte[] badCode = in.createByteArray(); final byte numSubGroups = in.readByte(); final List<Long> bisSyncState = in.readArrayList(Long.class.getClassLoader(), Long.class); diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java b/framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java index 56809f93e9..1c2f7d3226 100644 --- a/framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java +++ b/framework/java/android/bluetooth/BluetoothLeBroadcastSettings.java @@ -162,13 +162,7 @@ public final class BluetoothLeBroadcastSettings implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeBoolean(mIsPublicBroadcast); BluetoothUtils.writeStringToParcel(out, mBroadcastName); - if (mBroadcastCode != null) { - out.writeInt(mBroadcastCode.length); - out.writeByteArray(mBroadcastCode); - } else { - // -1 indicates missing broadcast code - out.writeInt(-1); - } + out.writeByteArray(mBroadcastCode); out.writeTypedObject(mPublicBroadcastMetadata, 0); out.writeTypedList(mSubgroupSettings); } @@ -185,14 +179,7 @@ public final class BluetoothLeBroadcastSettings implements Parcelable { Builder builder = new Builder(); builder.setPublicBroadcast(in.readBoolean()); builder.setBroadcastName(in.readString()); - final int codeLen = in.readInt(); - byte[] broadcastCode = null; - if (codeLen != -1) { - broadcastCode = new byte[codeLen]; - if (codeLen >= 0) { - in.readByteArray(broadcastCode); - } - } + byte[] broadcastCode = in.createByteArray(); builder.setBroadcastCode(broadcastCode); builder.setPublicBroadcastMetadata( in.readTypedObject(BluetoothLeAudioContentMetadata.CREATOR)); diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 5848ebba1c..cc52ea4cbd 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -1313,6 +1313,31 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* } break; case BTA_DM_INQ_RES_EVT: { + RawAddress& bdaddr = p_search_data->inq_res.bd_addr; + + // Do not update device properties of already bonded devices. + if (com::android::bluetooth::flags::guard_bonded_device_properties() && + btm_sec_is_a_bonded_dev(bdaddr)) { + log::debug("Ignore device properties from discovery results for the bonded device: {}", + bdaddr); + + bool restrict_report = + osi_property_get_bool("bluetooth.restrict_discovered_device.enabled", false); + if (restrict_report && p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BLE && + !(p_search_data->inq_res.ble_evt_type & BTM_BLE_CONNECTABLE_MASK)) { + log::debug("Ble device {} is not connectable", bdaddr); + break; + } + + bt_property_t bt_property[] = { + {BT_PROPERTY_BDADDR, sizeof(bdaddr), &bdaddr}, + {BT_PROPERTY_REMOTE_RSSI, sizeof(p_search_data->inq_res.rssi), + &(p_search_data->inq_res.rssi)}}; + GetInterfaceToProfiles()->events->invoke_device_found_cb(ARRAY_SIZE(bt_property), + bt_property); + break; + } + /* inquiry result */ bt_bdname_t bdname; uint8_t remote_name_len = 0; @@ -1323,7 +1348,6 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_search_data->inq_res.remt_name_not_required = check_eir_remote_name(p_search_data, NULL, NULL); } - RawAddress& bdaddr = p_search_data->inq_res.bd_addr; log::verbose("addr:{} device_type=0x{:x}", bdaddr, p_search_data->inq_res.device_type); bdname.name[0] = 0; diff --git a/system/main/shim/le_scanning_manager.cc b/system/main/shim/le_scanning_manager.cc index 8214dea25c..8aaa13ed8b 100644 --- a/system/main/shim/le_scanning_manager.cc +++ b/system/main/shim/le_scanning_manager.cc @@ -21,6 +21,7 @@ #include <base/functional/bind.h> #include <base/threading/thread.h> #include <bluetooth/log.h> +#include <com_android_bluetooth_flags.h> #include <hardware/bluetooth.h> #include "btif/include/btif_common.h" @@ -37,6 +38,7 @@ #include "stack/include/advertise_data_parser.h" #include "stack/include/bt_dev_class.h" #include "stack/include/btm_log_history.h" +#include "stack/include/btm_sec_api.h" #include "stack/include/btm_status.h" #include "storage/device.h" #include "storage/le_device.h" @@ -467,9 +469,13 @@ void BleScannerInterfaceImpl::OnScanResult(uint16_t event_type, uint8_t address_ btm_ble_process_adv_addr(raw_address, &ble_addr_type); } - do_in_jni_thread(base::BindOnce(&BleScannerInterfaceImpl::handle_remote_properties, - base::Unretained(this), raw_address, ble_addr_type, - advertising_data)); + // Do not update device properties of already bonded devices. + if (!com::android::bluetooth::flags::guard_bonded_device_properties() || + !btm_sec_is_a_bonded_dev(raw_address)) { + do_in_jni_thread(base::BindOnce(&BleScannerInterfaceImpl::handle_remote_properties, + base::Unretained(this), raw_address, ble_addr_type, + advertising_data)); + } do_in_jni_thread(base::BindOnce( &ScanningCallbacks::OnScanResult, base::Unretained(scanning_callbacks_), event_type, diff --git a/system/stack/avct/avct_lcb_act.cc b/system/stack/avct/avct_lcb_act.cc index 7770cd9e4a..6b199202de 100644 --- a/system/stack/avct/avct_lcb_act.cc +++ b/system/stack/avct/avct_lcb_act.cc @@ -718,10 +718,13 @@ void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { p = (uint8_t*)(p_buf + 1) + p_buf->offset; AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ); UINT16_TO_BE_STREAM(p, pid); + + uint16_t len = p_buf->len; + if (stack::l2cap::get_interface().L2CA_DataWrite(p_lcb->ch_lcid, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} lcid:0x{:04x} len:{}", p_lcb->peer_addr, - p_lcb->ch_lcid, p_buf->len); + p_lcb->ch_lcid, len); } } } diff --git a/system/stack/avdt/avdt_msg.cc b/system/stack/avdt/avdt_msg.cc index 09d9c6dd81..eb623b1b2a 100644 --- a/system/stack/avdt/avdt_msg.cc +++ b/system/stack/avdt/avdt_msg.cc @@ -29,6 +29,7 @@ #define LOG_TAG "bluetooth-a2dp" #include <bluetooth/log.h> +#include <com_android_bluetooth_flags.h> #include <string.h> #include <cstdint> @@ -1544,6 +1545,15 @@ void avdt_msg_ind(AvdtpCcb* p_ccb, BT_HDR* p_buf) { avdt_msg_send_grej(p_ccb, sig, &msg); } } + + /* validate reject/response against cached sig */ + if (com::android::bluetooth::flags::btsec_avdt_msg_ind_type_confusion()) { + if (((msg_type == AVDT_MSG_TYPE_RSP) || (msg_type == AVDT_MSG_TYPE_REJ)) && + (p_ccb->p_curr_cmd == nullptr || p_ccb->p_curr_cmd->event != sig)) { + log::warn("Dropping msg with mismatched sig; sig={}", sig); + ok = false; + } + } } log::verbose("msg_type={}, sig={}", msg_type, sig); diff --git a/system/stack/bnep/bnep_main.cc b/system/stack/bnep/bnep_main.cc index add8bad93d..a9c36379db 100644 --- a/system/stack/bnep/bnep_main.cc +++ b/system/stack/bnep/bnep_main.cc @@ -300,10 +300,12 @@ static void bnep_congestion_ind(uint16_t l2cap_cid, bool is_congested) { break; } + uint16_t len = p_buf->len; + if (stack::l2cap::get_interface().L2CA_DataWrite(l2cap_cid, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_bcb->rem_bda, l2cap_cid, - p_buf->len); + len); } } } diff --git a/system/stack/bnep/bnep_utils.cc b/system/stack/bnep/bnep_utils.cc index 64ea5f2501..7a9a975584 100644 --- a/system/stack/bnep/bnep_utils.cc +++ b/system/stack/bnep/bnep_utils.cc @@ -417,10 +417,11 @@ void bnepu_check_send_packet(tBNEP_CONN* p_bcb, BT_HDR* p_buf) { fixed_queue_enqueue(p_bcb->xmit_q, p_buf); } } else { + uint16_t len = p_buf->len; if (stack::l2cap::get_interface().L2CA_DataWrite(p_bcb->l2cap_cid, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_bcb->rem_bda, - p_bcb->l2cap_cid, p_buf->len); + p_bcb->l2cap_cid, len); } } } diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc index 9afa217b20..5251baa7eb 100644 --- a/system/stack/btm/btm_sec.cc +++ b/system/stack/btm/btm_sec.cc @@ -1397,6 +1397,14 @@ static bool btm_sec_is_upgrade_possible(tBTM_SEC_DEV_REC* p_dev_rec, bool is_ori * security level database */ is_possible = true; } + + /*if authentication is requirement & currently on temp bonding + * trigger pairing */ + if (com::android::bluetooth::flags::upgrade_temp_bonding_on_auth_req() && + (p_dev_rec->sec_rec.security_required & BTM_SEC_OUT_AUTHENTICATE) && + p_dev_rec->sec_rec.is_bond_type_temporary()) { + is_possible = true; + } } log::verbose("is_possible: {} sec_flags: 0x{:x}", is_possible, p_dev_rec->sec_rec.sec_flags); return is_possible; @@ -3320,6 +3328,10 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_en if (status == HCI_ERR_KEY_MISSING) { log::info("Remote key missing - will report"); bta_dm_remote_key_missing(p_dev_rec->ble.pseudo_addr); + if (com::android::bluetooth::flags::sec_disconnect_on_le_key_missing()) { + btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_HOST_REJECT_SECURITY, + p_dev_rec->ble_hci_handle, "encryption_change:key_missing"); + } return; } @@ -3485,6 +3497,13 @@ void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t return; } + if (com::android::bluetooth::flags::disconnect_on_encryption_failure()) { + if (status != HCI_SUCCESS && encr_enable == 0) { + log::error("Encryption failure {}, disconnecting {}", status, handle); + btm_sec_disconnect(handle, HCI_ERR_AUTH_FAILURE, + "stack::btu::btu_hcif::encryption_change_evt Encryption Failure"); + } + } btm_acl_encrypt_change(handle, static_cast<tHCI_STATUS>(status), encr_enable); btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status), encr_enable, 0); } diff --git a/system/stack/hid/hidd_conn.cc b/system/stack/hid/hidd_conn.cc index b50516d8a8..7276af8acd 100644 --- a/system/stack/hid/hidd_conn.cc +++ b/system/stack/hid/hidd_conn.cc @@ -95,10 +95,10 @@ static void hidd_check_config_done() { // send outstanding data on intr if (hd_cb.pending_data) { + uint16_t len = hd_cb.pending_data->len; if (stack::l2cap::get_interface().L2CA_DataWrite(p_hcon->intr_cid, hd_cb.pending_data) != tL2CAP_DW_RESULT::SUCCESS) { - log::warn("Unable to write L2CAP data cid:{} len:{}", p_hcon->intr_cid, - hd_cb.pending_data->len); + log::warn("Unable to write L2CAP data cid:{} len:{}", p_hcon->intr_cid, len); } hd_cb.pending_data = NULL; } diff --git a/system/stack/rfcomm/rfc_ts_frames.cc b/system/stack/rfcomm/rfc_ts_frames.cc index fe92bb7ef0..957ace7b7f 100644 --- a/system/stack/rfcomm/rfc_ts_frames.cc +++ b/system/stack/rfcomm/rfc_ts_frames.cc @@ -197,10 +197,11 @@ void rfc_send_buf_uih(tRFC_MCB* p_mcb, uint8_t dlci, BT_HDR* p_buf) { if (dlci == RFCOMM_MX_DLCI) { rfc_check_send_cmd(p_mcb, p_buf); } else { + uint16_t len = p_buf->len; if (stack::l2cap::get_interface().L2CA_DataWrite(p_mcb->lcid, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_mcb->bd_addr, p_mcb->lcid, - p_buf->len); + len); } } } diff --git a/system/stack/rfcomm/rfc_utils.cc b/system/stack/rfcomm/rfc_utils.cc index 87beaaf566..55845a9f76 100644 --- a/system/stack/rfcomm/rfc_utils.cc +++ b/system/stack/rfcomm/rfc_utils.cc @@ -428,9 +428,10 @@ void rfc_check_send_cmd(tRFC_MCB* p_mcb, BT_HDR* p_buf) { if (p == NULL) { break; } + uint16_t len = p->len; if (stack::l2cap::get_interface().L2CA_DataWrite(p_mcb->lcid, p) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_mcb->bd_addr, p_mcb->lcid, - p->len); + len); } } } diff --git a/system/stack/sdp/sdp_discovery.cc b/system/stack/sdp/sdp_discovery.cc index d3284892c8..6aba1993af 100644 --- a/system/stack/sdp/sdp_discovery.cc +++ b/system/stack/sdp/sdp_discovery.cc @@ -180,7 +180,7 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len, uint8_ if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_cmd) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, - p_ccb->connection_id, p_cmd->len); + p_ccb->connection_id, p - p_start); } /* Start inactivity timer */ @@ -708,7 +708,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_msg) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, - p_ccb->connection_id, p_msg->len); + p_ccb->connection_id, p - p_start); } /* Start inactivity timer */ @@ -877,7 +877,7 @@ static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, uint8_t* if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_msg) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, - p_ccb->connection_id, p_msg->len); + p_ccb->connection_id, p - p_start); } /* Start inactivity timer */ diff --git a/system/stack/sdp/sdp_server.cc b/system/stack/sdp/sdp_server.cc index 864280cba4..0f379708e9 100644 --- a/system/stack/sdp/sdp_server.cc +++ b/system/stack/sdp/sdp_server.cc @@ -300,7 +300,7 @@ static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num, uint16_t if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, - p_ccb->connection_id, p_buf->len); + p_ccb->connection_id, p_rsp - p_rsp_start); } } @@ -564,7 +564,7 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, uint16 if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, - p_ccb->connection_id, p_buf->len); + p_ccb->connection_id, p_rsp - p_rsp_start); } } @@ -921,7 +921,7 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, - p_ccb->connection_id, p_buf->len); + p_ccb->connection_id, p_rsp - p_rsp_start); } } diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc index c625217c7c..a9a8aafbf7 100644 --- a/system/stack/smp/smp_act.cc +++ b/system/stack/smp/smp_act.cc @@ -1954,6 +1954,18 @@ void smp_process_secure_connection_oob_data(tSMP_CB* p_cb, tSMP_INT_DATA* /* p_d p_cb->local_random = {0}; } + if (com::android::bluetooth::flags::btsec_le_oob_pairing()) { + if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && !p_sc_oob_data->loc_oob_data.present) { + log::warn( + "local OOB data is not present but peer claims to have received it; dropping " + "connection"); + tSMP_INT_DATA smp_int_data{}; + smp_int_data.status = SMP_OOB_FAIL; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); + return; + } + } + if (!p_sc_oob_data->peer_oob_data.present) { log::verbose("peer OOB data is absent"); p_cb->peer_random = {0}; |