summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-16 04:15:29 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-16 04:15:29 +0000
commit1d9b9ab57d844b18b3b1b4297725141e7788109b (patch)
treeca8ef894d40a716f7ffcc8397279af91a8e349d3
parent73d093712b0dbb59ef47f5d63087b6cb558c454a (diff)
parent0a9a6bfc2583e6998f192be2489a55b85b795041 (diff)
downloadbase-android11-d2-release.tar.gz
Merge cherrypicks of [15581311, 15581312, 15581313, 15581314, 15581326, 15581327, 15581138, 15581139, 15581140, 15581341, 15581342, 15581343, 15581344, 15581095, 15581315, 15581316, 15581317, 15581345, 15581328] into rvc-d2-releaseandroid-11.0.0_r48android-11.0.0_r47android11-d2-release
Change-Id: I2306983b2b63a7d42687062b374f29094cedc212
-rw-r--r--core/java/android/app/Notification.java13
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java4
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java10
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java3
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java28
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java21
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java12
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java8
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java18
11 files changed, 103 insertions, 17 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c273cf08d03b..132afabe82d1 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3029,6 +3029,19 @@ public class Notification implements Parcelable
}
/**
+ * Sets the token used for background operations for the pending intents associated with this
+ * notification.
+ *
+ * This token is automatically set during deserialization for you, you usually won't need to
+ * call this unless you want to change the existing token, if any.
+ *
+ * @hide
+ */
+ public void setAllowlistToken(@Nullable IBinder token) {
+ mWhitelistToken = token;
+ }
+
+ /**
* @hide
*/
public static void addFieldsFromContext(Context context, Notification notification) {
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 65ce1e7ef079..9cd568fe2aaf 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -207,7 +207,9 @@ public class PackageItemInfo {
return loadSafeLabel(pm, DEFAULT_MAX_LABEL_SIZE_PX, SAFE_STRING_FLAG_TRIM
| SAFE_STRING_FLAG_FIRST_LINE);
} else {
- return loadUnsafeLabel(pm);
+ // Trims the label string to the MAX_SAFE_LABEL_LENGTH. This is to prevent that the
+ // system is overwhelmed by an enormous string returned by the application.
+ return TextUtils.trimToSize(loadUnsafeLabel(pm), MAX_SAFE_LABEL_LENGTH);
}
}
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d6ee28b93f92..5c659123b027 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3780,6 +3780,8 @@
<string name="deny">Deny</string>
<string name="permission_request_notification_title">Permission requested</string>
<string name="permission_request_notification_with_subtitle">Permission requested\nfor account <xliff:g id="account" example="foo@gmail.com">%s</xliff:g>.</string>
+ <!-- Title and subtitle for notification shown when app request account access (two lines) [CHAR LIMIT=NONE] -->
+ <string name="permission_request_notification_for_app_with_subtitle">Permission requested by <xliff:g id="app" example="Gmail">%1$s</xliff:g>\nfor account <xliff:g id="account" example="foo@gmail.com">%2$s</xliff:g>.</string>
<!-- Message to show when an intent automatically switches users into the personal profile. -->
<string name="forward_intent_to_owner">You\'re using this app outside of your work profile</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3ef0a8dc9daa..3c2aa621864b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -548,6 +548,7 @@
<java-symbol type="string" name="notification_title" />
<java-symbol type="string" name="other_networks_no_internet" />
<java-symbol type="string" name="permission_request_notification_with_subtitle" />
+ <java-symbol type="string" name="permission_request_notification_for_app_with_subtitle" />
<java-symbol type="string" name="prepend_shortcut_label" />
<java-symbol type="string" name="private_dns_broken_detailed" />
<java-symbol type="string" name="paste_as_plain_text" />
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index e6fa866df3ab..a831bb86009c 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -348,15 +348,19 @@ public class VectorDrawable extends Drawable {
private final Rect mTmpBounds = new Rect();
public VectorDrawable() {
- this(new VectorDrawableState(null), null);
+ this(null, null);
}
/**
* The one constructor to rule them all. This is called by all public
* constructors to set the state and initialize local properties.
*/
- private VectorDrawable(@NonNull VectorDrawableState state, @Nullable Resources res) {
- mVectorState = state;
+ private VectorDrawable(@Nullable VectorDrawableState state, @Nullable Resources res) {
+ // As the mutable, not-thread-safe native instance is stored in VectorDrawableState, we
+ // need to always do a defensive copy even if mutate() isn't called. Otherwise
+ // draw() being called on 2 different VectorDrawable instances could still hit the same
+ // underlying native object.
+ mVectorState = new VectorDrawableState(state);
updateLocalState(res);
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
index 4d1fb38329e9..a687bb89fd75 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
@@ -195,9 +195,12 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addDataScheme("package");
+ mContext.registerReceiver(this, filter);
filter.addAction(PLUGIN_CHANGED);
filter.addAction(DISABLE_PLUGIN);
filter.addDataScheme("package");
+ mContext.registerReceiver(this, filter, PluginInstanceManager.PLUGIN_PERMISSION, null);
mContext.registerReceiver(this, filter);
filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
mContext.registerReceiver(this, filter);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index a1cbd00e360f..9a3ab4403831 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -73,6 +73,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.net.CaptivePortal;
@@ -4609,6 +4610,25 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ private int getAppUid(final String app, final int userId) {
+ final PackageManager pm = mContext.getPackageManager();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return pm.getPackageUidAsUser(app, userId);
+ } catch (NameNotFoundException e) {
+ return -1;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private void verifyCallingUidAndPackage(String packageName, int callingUid) {
+ final int userId = UserHandle.getUserId(callingUid);
+ if (getAppUid(packageName, userId) != callingUid) {
+ throw new SecurityException(packageName + " does not belong to uid " + callingUid);
+ }
+ }
+
/**
* Starts the VPN based on the stored profile for the given package
*
@@ -4620,7 +4640,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
@Override
public void startVpnProfile(@NonNull String packageName) {
- final int user = UserHandle.getUserId(Binder.getCallingUid());
+ final int callingUid = Binder.getCallingUid();
+ verifyCallingUidAndPackage(packageName, callingUid);
+ final int user = UserHandle.getUserId(callingUid);
synchronized (mVpns) {
throwIfLockdownEnabled();
mVpns.get(user).startVpnProfile(packageName, mKeyStore);
@@ -4637,7 +4659,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
@Override
public void stopVpnProfile(@NonNull String packageName) {
- final int user = UserHandle.getUserId(Binder.getCallingUid());
+ final int callingUid = Binder.getCallingUid();
+ verifyCallingUidAndPackage(packageName, callingUid);
+ final int user = UserHandle.getUserId(callingUid);
synchronized (mVpns) {
mVpns.get(user).stopVpnProfile(packageName);
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 2e04f9c2bcd1..db3c25a7e43a 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -449,7 +449,7 @@ public class AccountManagerService
if (!checkAccess || hasAccountAccess(account, packageName,
UserHandle.getUserHandleForUid(uid))) {
cancelNotification(getCredentialPermissionNotificationId(account,
- AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid), packageName,
+ AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid),
UserHandle.getUserHandleForUid(uid));
}
}
@@ -3051,8 +3051,8 @@ public class AccountManagerService
String authTokenType = intent.getStringExtra(
GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE);
final String titleAndSubtitle =
- mContext.getString(R.string.permission_request_notification_with_subtitle,
- account.name);
+ mContext.getString(R.string.permission_request_notification_for_app_with_subtitle,
+ getApplicationLabel(packageName), account.name);
final int index = titleAndSubtitle.indexOf('\n');
String title = titleAndSubtitle;
String subtitle = "";
@@ -3075,7 +3075,16 @@ public class AccountManagerService
null, user))
.build();
installNotification(getCredentialPermissionNotificationId(
- account, authTokenType, uid), n, packageName, user.getIdentifier());
+ account, authTokenType, uid), n, "android", user.getIdentifier());
+ }
+
+ private String getApplicationLabel(String packageName) {
+ try {
+ return mPackageManager.getApplicationLabel(
+ mPackageManager.getApplicationInfo(packageName, 0)).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ return packageName;
+ }
}
private Intent newGrantCredentialsPermissionIntent(Account account, String packageName,
@@ -3111,7 +3120,7 @@ public class AccountManagerService
nId = accounts.credentialsPermissionNotificationIds.get(key);
if (nId == null) {
String tag = TAG + ":" + SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION
- + ":" + account.hashCode() + ":" + authTokenType.hashCode();
+ + ":" + account.hashCode() + ":" + authTokenType.hashCode() + ":" + uid;
int id = SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION;
nId = new NotificationId(tag, id);
accounts.credentialsPermissionNotificationIds.put(key, nId);
@@ -4064,7 +4073,7 @@ public class AccountManagerService
private void handleAuthenticatorResponse(boolean accessGranted) throws RemoteException {
cancelNotification(getCredentialPermissionNotificationId(account,
- AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid), packageName,
+ AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid),
UserHandle.getUserHandleForUid(uid));
if (callback != null) {
Bundle result = new Bundle();
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 42bd8c512806..4873440b53c1 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1370,7 +1370,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
builder.setSmallIcon(R.drawable.stat_notify_error);
- final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
+ final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template,
+ mContext.getPackageName());
builder.setDeleteIntent(PendingIntent.getBroadcast(
mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
@@ -1456,7 +1457,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
builder.setSmallIcon(R.drawable.stat_notify_error);
- final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template);
+ final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template,
+ mContext.getPackageName());
builder.setDeleteIntent(PendingIntent.getBroadcast(
mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
@@ -5061,17 +5063,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
return new Intent(ACTION_ALLOW_BACKGROUND);
}
- private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
+ private static Intent buildSnoozeWarningIntent(NetworkTemplate template, String targetPackage) {
final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
+ intent.setPackage(targetPackage);
return intent;
}
- private static Intent buildSnoozeRapidIntent(NetworkTemplate template) {
+ private static Intent buildSnoozeRapidIntent(NetworkTemplate template, String targetPackage) {
final Intent intent = new Intent(ACTION_SNOOZE_RAPID);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
+ intent.setPackage(targetPackage);
return intent;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index dc551e14b970..629a918584fe 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3859,6 +3859,7 @@ public class NotificationManagerService extends SystemService {
}
}
+ /** Notifications returned here will have allowlistToken stripped from them. */
private StatusBarNotification sanitizeSbn(String pkg, int userId,
StatusBarNotification sbn) {
if (sbn.getUserId() == userId) {
@@ -3866,11 +3867,16 @@ public class NotificationManagerService extends SystemService {
// We could pass back a cloneLight() but clients might get confused and
// try to send this thing back to notify() again, which would not work
// very well.
+ Notification notification = sbn.getNotification().clone();
+ // Remove background token before returning notification to untrusted app, this
+ // ensures the app isn't able to perform background operations that are
+ // associated with notification interactions.
+ notification.setAllowlistToken(null);
return new StatusBarNotification(
sbn.getPackageName(),
sbn.getOpPkg(),
sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
- sbn.getNotification().clone(),
+ notification,
sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime());
}
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index a5554c740e7f..e9301d1dea9d 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1224,6 +1224,9 @@ public class ConnectivityServiceTest {
Arrays.asList(new UserInfo[] {
new UserInfo(VPN_USER, "", 0),
}));
+ final int userId = UserHandle.getCallingUserId();
+ final UserInfo primaryUser = new UserInfo(userId, "", UserInfo.FLAG_PRIMARY);
+ doReturn(primaryUser).when(mUserManager).getUserInfo(eq(userId));
final ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
@@ -1368,6 +1371,9 @@ public class ConnectivityServiceTest {
buildPackageInfo(/* SYSTEM */ false, APP2_UID),
buildPackageInfo(/* SYSTEM */ false, VPN_UID)
}));
+ final int userId = UserHandle.getCallingUserId();
+ when(mPackageManager.getPackageUidAsUser(TEST_PACKAGE_NAME, userId))
+ .thenReturn(Process.myUid());
}
private void verifyActiveNetwork(int transport) {
@@ -7069,6 +7075,18 @@ public class ConnectivityServiceTest {
}
@Test
+ public void testStartVpnProfileFromDiffPackage() throws Exception {
+ final String notMyVpnPkg = "com.not.my.vpn";
+ assertThrows(SecurityException.class, () -> mService.startVpnProfile(notMyVpnPkg));
+ }
+
+ @Test
+ public void testStopVpnProfileFromDiffPackage() throws Exception {
+ final String notMyVpnPkg = "com.not.my.vpn";
+ assertThrows(SecurityException.class, () -> mService.stopVpnProfile(notMyVpnPkg));
+ }
+
+ @Test
public void testUidUpdateChangesInterfaceFilteringRule() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");