Skip to content

Commit 7f7fc25

Browse files
committed
Merge tag 'android-11.0.0_r46' into staging/lineage-18.1_merge-android-11.0.0_r46
Android 11.0.0 Release 46 (RQ3A.211001.001) * tag 'android-11.0.0_r46': Make sure that only the owner can call stopVpnProfile() DO NOT MERGE Apply a maximum char count to the load label api Send targeted broadcasts to prevent other apps from receiving them. Guard DISABLE_PLUGIN with PLUGIN permission. Fix a potential thread safety issue in VectorDrawable Fix background bypass via notifications Change ownership of the account request notification. Change-Id: I30615811a1c2ee4d670c643d892d1a9f275e2a9c
2 parents cf0606c + 49d8b98 commit 7f7fc25

11 files changed

Lines changed: 103 additions & 17 deletions

File tree

core/java/android/app/Notification.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3028,6 +3028,19 @@ public void setLatestEventInfo(Context context,
30283028
builder.build(); // callers expect this notification to be ready to use
30293029
}
30303030

3031+
/**
3032+
* Sets the token used for background operations for the pending intents associated with this
3033+
* notification.
3034+
*
3035+
* This token is automatically set during deserialization for you, you usually won't need to
3036+
* call this unless you want to change the existing token, if any.
3037+
*
3038+
* @hide
3039+
*/
3040+
public void setAllowlistToken(@Nullable IBinder token) {
3041+
mWhitelistToken = token;
3042+
}
3043+
30313044
/**
30323045
* @hide
30333046
*/

core/java/android/content/pm/PackageItemInfo.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,9 @@ public PackageItemInfo(PackageItemInfo orig) {
207207
return loadSafeLabel(pm, DEFAULT_MAX_LABEL_SIZE_PX, SAFE_STRING_FLAG_TRIM
208208
| SAFE_STRING_FLAG_FIRST_LINE);
209209
} else {
210-
return loadUnsafeLabel(pm);
210+
// Trims the label string to the MAX_SAFE_LABEL_LENGTH. This is to prevent that the
211+
// system is overwhelmed by an enormous string returned by the application.
212+
return TextUtils.trimToSize(loadUnsafeLabel(pm), MAX_SAFE_LABEL_LENGTH);
211213
}
212214
}
213215

core/res/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3780,6 +3780,8 @@
37803780
<string name="deny">Deny</string>
37813781
<string name="permission_request_notification_title">Permission requested</string>
37823782
<string name="permission_request_notification_with_subtitle">Permission requested\nfor account <xliff:g id="account" example="foo@gmail.com">%s</xliff:g>.</string>
3783+
<!-- Title and subtitle for notification shown when app request account access (two lines) [CHAR LIMIT=NONE] -->
3784+
<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>
37833785

37843786
<!-- Message to show when an intent automatically switches users into the personal profile. -->
37853787
<string name="forward_intent_to_owner">You\'re using this app outside of your work profile</string>

core/res/res/values/symbols.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@
548548
<java-symbol type="string" name="notification_title" />
549549
<java-symbol type="string" name="other_networks_no_internet" />
550550
<java-symbol type="string" name="permission_request_notification_with_subtitle" />
551+
<java-symbol type="string" name="permission_request_notification_for_app_with_subtitle" />
551552
<java-symbol type="string" name="prepend_shortcut_label" />
552553
<java-symbol type="string" name="private_dns_broken_detailed" />
553554
<java-symbol type="string" name="paste_as_plain_text" />

graphics/java/android/graphics/drawable/VectorDrawable.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,15 +348,19 @@ public class VectorDrawable extends Drawable {
348348
private final Rect mTmpBounds = new Rect();
349349

350350
public VectorDrawable() {
351-
this(new VectorDrawableState(null), null);
351+
this(null, null);
352352
}
353353

354354
/**
355355
* The one constructor to rule them all. This is called by all public
356356
* constructors to set the state and initialize local properties.
357357
*/
358-
private VectorDrawable(@NonNull VectorDrawableState state, @Nullable Resources res) {
359-
mVectorState = state;
358+
private VectorDrawable(@Nullable VectorDrawableState state, @Nullable Resources res) {
359+
// As the mutable, not-thread-safe native instance is stored in VectorDrawableState, we
360+
// need to always do a defensive copy even if mutate() isn't called. Otherwise
361+
// draw() being called on 2 different VectorDrawable instances could still hit the same
362+
// underlying native object.
363+
mVectorState = new VectorDrawableState(state);
360364
updateLocalState(res);
361365
}
362366

packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,12 @@ private void startListening() {
195195
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
196196
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
197197
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
198+
filter.addDataScheme("package");
199+
mContext.registerReceiver(this, filter);
198200
filter.addAction(PLUGIN_CHANGED);
199201
filter.addAction(DISABLE_PLUGIN);
200202
filter.addDataScheme("package");
203+
mContext.registerReceiver(this, filter, PluginInstanceManager.PLUGIN_PERMISSION, null);
201204
mContext.registerReceiver(this, filter);
202205
filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
203206
mContext.registerReceiver(this, filter);

services/core/java/com/android/server/ConnectivityService.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import android.content.Intent;
7474
import android.content.IntentFilter;
7575
import android.content.pm.PackageManager;
76+
import android.content.pm.PackageManager.NameNotFoundException;
7677
import android.content.res.Configuration;
7778
import android.database.ContentObserver;
7879
import android.net.CaptivePortal;
@@ -4788,6 +4789,25 @@ public void deleteVpnProfile(@NonNull String packageName) {
47884789
}
47894790
}
47904791

4792+
private int getAppUid(final String app, final int userId) {
4793+
final PackageManager pm = mContext.getPackageManager();
4794+
final long token = Binder.clearCallingIdentity();
4795+
try {
4796+
return pm.getPackageUidAsUser(app, userId);
4797+
} catch (NameNotFoundException e) {
4798+
return -1;
4799+
} finally {
4800+
Binder.restoreCallingIdentity(token);
4801+
}
4802+
}
4803+
4804+
private void verifyCallingUidAndPackage(String packageName, int callingUid) {
4805+
final int userId = UserHandle.getUserId(callingUid);
4806+
if (getAppUid(packageName, userId) != callingUid) {
4807+
throw new SecurityException(packageName + " does not belong to uid " + callingUid);
4808+
}
4809+
}
4810+
47914811
/**
47924812
* Starts the VPN based on the stored profile for the given package
47934813
*
@@ -4799,7 +4819,9 @@ public void deleteVpnProfile(@NonNull String packageName) {
47994819
*/
48004820
@Override
48014821
public void startVpnProfile(@NonNull String packageName) {
4802-
final int user = UserHandle.getUserId(Binder.getCallingUid());
4822+
final int callingUid = Binder.getCallingUid();
4823+
verifyCallingUidAndPackage(packageName, callingUid);
4824+
final int user = UserHandle.getUserId(callingUid);
48034825
synchronized (mVpns) {
48044826
throwIfLockdownEnabled();
48054827
mVpns.get(user).startVpnProfile(packageName, mKeyStore);
@@ -4816,7 +4838,9 @@ public void startVpnProfile(@NonNull String packageName) {
48164838
*/
48174839
@Override
48184840
public void stopVpnProfile(@NonNull String packageName) {
4819-
final int user = UserHandle.getUserId(Binder.getCallingUid());
4841+
final int callingUid = Binder.getCallingUid();
4842+
verifyCallingUidAndPackage(packageName, callingUid);
4843+
final int user = UserHandle.getUserId(callingUid);
48204844
synchronized (mVpns) {
48214845
mVpns.get(user).stopVpnProfile(packageName);
48224846
}

services/core/java/com/android/server/accounts/AccountManagerService.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ private void cancelAccountAccessRequestNotificationIfNeeded(Account account,
449449
if (!checkAccess || hasAccountAccess(account, packageName,
450450
UserHandle.getUserHandleForUid(uid))) {
451451
cancelNotification(getCredentialPermissionNotificationId(account,
452-
AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid), packageName,
452+
AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid),
453453
UserHandle.getUserHandleForUid(uid));
454454
}
455455
}
@@ -3051,8 +3051,8 @@ private void createNoCredentialsPermissionNotification(Account account, Intent i
30513051
String authTokenType = intent.getStringExtra(
30523052
GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE);
30533053
final String titleAndSubtitle =
3054-
mContext.getString(R.string.permission_request_notification_with_subtitle,
3055-
account.name);
3054+
mContext.getString(R.string.permission_request_notification_for_app_with_subtitle,
3055+
getApplicationLabel(packageName), account.name);
30563056
final int index = titleAndSubtitle.indexOf('\n');
30573057
String title = titleAndSubtitle;
30583058
String subtitle = "";
@@ -3075,7 +3075,16 @@ private void createNoCredentialsPermissionNotification(Account account, Intent i
30753075
null, user))
30763076
.build();
30773077
installNotification(getCredentialPermissionNotificationId(
3078-
account, authTokenType, uid), n, packageName, user.getIdentifier());
3078+
account, authTokenType, uid), n, "android", user.getIdentifier());
3079+
}
3080+
3081+
private String getApplicationLabel(String packageName) {
3082+
try {
3083+
return mPackageManager.getApplicationLabel(
3084+
mPackageManager.getApplicationInfo(packageName, 0)).toString();
3085+
} catch (PackageManager.NameNotFoundException e) {
3086+
return packageName;
3087+
}
30793088
}
30803089

30813090
private Intent newGrantCredentialsPermissionIntent(Account account, String packageName,
@@ -3111,7 +3120,7 @@ private NotificationId getCredentialPermissionNotificationId(Account account,
31113120
nId = accounts.credentialsPermissionNotificationIds.get(key);
31123121
if (nId == null) {
31133122
String tag = TAG + ":" + SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION
3114-
+ ":" + account.hashCode() + ":" + authTokenType.hashCode();
3123+
+ ":" + account.hashCode() + ":" + authTokenType.hashCode() + ":" + uid;
31153124
int id = SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION;
31163125
nId = new NotificationId(tag, id);
31173126
accounts.credentialsPermissionNotificationIds.put(key, nId);
@@ -4064,7 +4073,7 @@ public void onError(int errorCode, String errorMessage) throws RemoteException {
40644073

40654074
private void handleAuthenticatorResponse(boolean accessGranted) throws RemoteException {
40664075
cancelNotification(getCredentialPermissionNotificationId(account,
4067-
AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid), packageName,
4076+
AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid),
40684077
UserHandle.getUserHandleForUid(uid));
40694078
if (callback != null) {
40704079
Bundle result = new Bundle();

services/core/java/com/android/server/net/NetworkPolicyManagerService.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,8 @@ private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes
13811381

13821382
builder.setSmallIcon(R.drawable.stat_notify_error);
13831383

1384-
final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
1384+
final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template,
1385+
mContext.getPackageName());
13851386
builder.setDeleteIntent(PendingIntent.getBroadcast(
13861387
mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
13871388

@@ -1467,7 +1468,8 @@ private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes
14671468

14681469
builder.setSmallIcon(R.drawable.stat_notify_error);
14691470

1470-
final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template);
1471+
final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template,
1472+
mContext.getPackageName());
14711473
builder.setDeleteIntent(PendingIntent.getBroadcast(
14721474
mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
14731475

@@ -5141,17 +5143,19 @@ private static Intent buildAllowBackgroundDataIntent() {
51415143
return new Intent(ACTION_ALLOW_BACKGROUND);
51425144
}
51435145

5144-
private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
5146+
private static Intent buildSnoozeWarningIntent(NetworkTemplate template, String targetPackage) {
51455147
final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
51465148
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
51475149
intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
5150+
intent.setPackage(targetPackage);
51485151
return intent;
51495152
}
51505153

5151-
private static Intent buildSnoozeRapidIntent(NetworkTemplate template) {
5154+
private static Intent buildSnoozeRapidIntent(NetworkTemplate template, String targetPackage) {
51525155
final Intent intent = new Intent(ACTION_SNOOZE_RAPID);
51535156
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
51545157
intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
5158+
intent.setPackage(targetPackage);
51555159
return intent;
51565160
}
51575161

services/core/java/com/android/server/notification/NotificationManagerService.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3898,18 +3898,24 @@ public ParceledListSlice<StatusBarNotification> getAppActiveNotifications(String
38983898
}
38993899
}
39003900

3901+
/** Notifications returned here will have allowlistToken stripped from them. */
39013902
private StatusBarNotification sanitizeSbn(String pkg, int userId,
39023903
StatusBarNotification sbn) {
39033904
if (sbn.getUserId() == userId) {
39043905
if (sbn.getPackageName().equals(pkg) || sbn.getOpPkg().equals(pkg)) {
39053906
// We could pass back a cloneLight() but clients might get confused and
39063907
// try to send this thing back to notify() again, which would not work
39073908
// very well.
3909+
Notification notification = sbn.getNotification().clone();
3910+
// Remove background token before returning notification to untrusted app, this
3911+
// ensures the app isn't able to perform background operations that are
3912+
// associated with notification interactions.
3913+
notification.setAllowlistToken(null);
39083914
return new StatusBarNotification(
39093915
sbn.getPackageName(),
39103916
sbn.getOpPkg(),
39113917
sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
3912-
sbn.getNotification().clone(),
3918+
notification,
39133919
sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime());
39143920
}
39153921
}

0 commit comments

Comments
 (0)