Skip to content

Commit a95cfc3

Browse files
Hui YuAndroid Build Coastguard Worker
authored andcommitted
Revert "BG-FGS-start while-in-use permission restriction improve..."
Revert "Add test cases for background startForeground() improvement." Revert submission 15081873-cherrypick-security_backport_183147114-an8dvy98fv Reason for revert: https://b.corp.google.com/issues/197066403#comment15 After the app calls Service.startForeground() to put the app into foreground service mode, the service has mAllowWhileInUsePermissionInFgs set, if it is true, the app/service can access location/camera/micophone. Some apps may call Service.startForeground() again (for any reason, could be a app's unintentional redundant call, could be that app want to update the notification of the foreground service), but at this moment the app has went into background mode, although the foreground service is still running. The second or later Service.startForeground() call may set mAllowWhileInUsePermissionInFgs to false and the app may lose location/camera/micophone access. This is incorrect because the foreground service is still running and we expect location/camera/micophone access to continue. The Samsung Voice Recorder app has run into this situation. Reverted Changes: I0aca484e5:BG-FGS-start while-in-use permission restriction i... I4988dbba1:Add test cases for background startForeground() im... Bug: 183147114 Bug: 197066403 Change-Id: Iad32e4391fa15bc252e50f9b858fe2e5225edb19 Merged-In: Idc88f274c7a323d175d65bb47eca041772ae9bb7 (cherry picked from commit c83a949722d0b879fb7ac73f3740e45d08b8efa6)
1 parent 197a074 commit a95cfc3

3 files changed

Lines changed: 21 additions & 112 deletions

File tree

services/core/java/com/android/server/am/ActiveServices.java

Lines changed: 21 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -734,8 +734,11 @@ ComponentName startServiceLocked(IApplicationThread caller, Intent service, Stri
734734
}
735735
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
736736

737-
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, r,
738-
allowBackgroundActivityStarts);
737+
if (!r.mAllowWhileInUsePermissionInFgs) {
738+
r.mAllowWhileInUsePermissionInFgs =
739+
shouldAllowWhileInUsePermissionInFgsLocked(callingPackage, callingPid,
740+
callingUid, service, r, allowBackgroundActivityStarts);
741+
}
739742

740743
return cmp;
741744
}
@@ -1397,6 +1400,14 @@ private void setServiceForegroundInnerLocked(final ServiceRecord r, int id,
13971400
+ String.format("0x%08X", manifestType)
13981401
+ " in service element of manifest file");
13991402
}
1403+
// If the foreground service is not started from TOP process, do not allow it to
1404+
// have while-in-use location/camera/microphone access.
1405+
if (!r.mAllowWhileInUsePermissionInFgs) {
1406+
Slog.w(TAG,
1407+
"Foreground service started from background can not have "
1408+
+ "location/camera/microphone access: service "
1409+
+ r.shortInstanceName);
1410+
}
14001411
}
14011412
boolean alreadyStartedOp = false;
14021413
boolean stopProcStatsOp = false;
@@ -1444,57 +1455,6 @@ && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
14441455
ignoreForeground = true;
14451456
}
14461457

1447-
if (!ignoreForeground) {
1448-
if (r.mStartForegroundCount == 0) {
1449-
/*
1450-
If the service was started with startService(), not
1451-
startForegroundService(), and if startForeground() isn't called within
1452-
mFgsStartForegroundTimeoutMs, then we check the state of the app
1453-
(who owns the service, which is the app that called startForeground())
1454-
again. If the app is in the foreground, or in any other cases where
1455-
FGS-starts are allowed, then we still allow the FGS to be started.
1456-
Otherwise, startForeground() would fail.
1457-
1458-
If the service was started with startForegroundService(), then the service
1459-
must call startForeground() within a timeout anyway, so we don't need this
1460-
check.
1461-
*/
1462-
if (!r.fgRequired) {
1463-
final long delayMs = SystemClock.elapsedRealtime() - r.createRealTime;
1464-
if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
1465-
resetFgsRestrictionLocked(r);
1466-
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.pid,
1467-
r.appInfo.uid, r, false);
1468-
EventLog.writeEvent(0x534e4554, "183147114",
1469-
r.appInfo.uid,
1470-
"call setFgsRestrictionLocked again due to "
1471-
+ "startForegroundTimeout");
1472-
}
1473-
}
1474-
} else if (r.mStartForegroundCount >= 1) {
1475-
// The second or later time startForeground() is called after service is
1476-
// started. Check for app state again.
1477-
final long delayMs = SystemClock.elapsedRealtime() -
1478-
r.mLastSetFgsRestrictionTime;
1479-
if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
1480-
resetFgsRestrictionLocked(r);
1481-
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.pid,
1482-
r.appInfo.uid, r, false);
1483-
EventLog.writeEvent(0x534e4554, "183147114", r.appInfo.uid,
1484-
"call setFgsRestrictionLocked for "
1485-
+ (r.mStartForegroundCount + 1) + "th startForeground");
1486-
}
1487-
}
1488-
// If the foreground service is not started from TOP process, do not allow it to
1489-
// have while-in-use location/camera/microphone access.
1490-
if (!r.mAllowWhileInUsePermissionInFgs) {
1491-
Slog.w(TAG,
1492-
"Foreground service started from background can not have "
1493-
+ "location/camera/microphone access: service "
1494-
+ r.shortInstanceName);
1495-
}
1496-
}
1497-
14981458
// Apps under strict background restrictions simply don't get to have foreground
14991459
// services, so now that we've enforced the startForegroundService() contract
15001460
// we only do the machinery of making the service foreground when the app
@@ -1530,7 +1490,6 @@ must call startForeground() within a timeout anyway, so we don't need this
15301490
active.mNumActive++;
15311491
}
15321492
r.isForeground = true;
1533-
r.mStartForegroundCount++;
15341493
if (!stopProcStatsOp) {
15351494
ServiceState stracker = r.getTracker();
15361495
if (stracker != null) {
@@ -1589,7 +1548,6 @@ must call startForeground() within a timeout anyway, so we don't need this
15891548
decActiveForegroundAppLocked(smap, r);
15901549
}
15911550
r.isForeground = false;
1592-
resetFgsRestrictionLocked(r);
15931551
ServiceState stracker = r.getTracker();
15941552
if (stracker != null) {
15951553
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
@@ -2149,7 +2107,12 @@ public void run() {
21492107
}
21502108
}
21512109

2152-
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, s, false);
2110+
if (!s.mAllowWhileInUsePermissionInFgs) {
2111+
s.mAllowWhileInUsePermissionInFgs =
2112+
shouldAllowWhileInUsePermissionInFgsLocked(callingPackage,
2113+
callingPid, callingUid,
2114+
service, s, false);
2115+
}
21532116

21542117
if (s.app != null) {
21552118
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
@@ -3445,7 +3408,7 @@ private final void bringDownServiceLocked(ServiceRecord r) {
34453408
r.isForeground = false;
34463409
r.foregroundId = 0;
34473410
r.foregroundNoti = null;
3448-
resetFgsRestrictionLocked(r);
3411+
r.mAllowWhileInUsePermissionInFgs = false;
34493412

34503413
// Clear start entries.
34513414
r.clearDeliveredStartsLocked();
@@ -4926,7 +4889,7 @@ private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
49264889
* @return true if allow, false otherwise.
49274890
*/
49284891
private boolean shouldAllowWhileInUsePermissionInFgsLocked(String callingPackage,
4929-
int callingPid, int callingUid, ServiceRecord r,
4892+
int callingPid, int callingUid, Intent intent, ServiceRecord r,
49304893
boolean allowBackgroundActivityStarts) {
49314894
// Is the background FGS start restriction turned on?
49324895
if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
@@ -4997,32 +4960,4 @@ private boolean shouldAllowWhileInUsePermissionInFgsLocked(String callingPackage
49974960
}
49984961
return false;
49994962
}
5000-
5001-
boolean canAllowWhileInUsePermissionInFgsLocked(int callingPid, int callingUid,
5002-
String callingPackage) {
5003-
return shouldAllowWhileInUsePermissionInFgsLocked(
5004-
callingPackage, callingPid, callingUid, null, false);
5005-
}
5006-
5007-
/**
5008-
* In R, mAllowWhileInUsePermissionInFgs is to allow while-in-use permissions in foreground
5009-
* service or not. while-in-use permissions in FGS started from background might be restricted.
5010-
* @param callingPackage caller app's package name.
5011-
* @param callingUid caller app's uid.
5012-
* @param r the service to start.
5013-
* @return true if allow, false otherwise.
5014-
*/
5015-
private void setFgsRestrictionLocked(String callingPackage,
5016-
int callingPid, int callingUid, ServiceRecord r,
5017-
boolean allowBackgroundActivityStarts) {
5018-
r.mLastSetFgsRestrictionTime = SystemClock.elapsedRealtime();
5019-
if (!r.mAllowWhileInUsePermissionInFgs) {
5020-
r.mAllowWhileInUsePermissionInFgs = shouldAllowWhileInUsePermissionInFgsLocked(
5021-
callingPackage, callingPid, callingUid, r, allowBackgroundActivityStarts);
5022-
}
5023-
}
5024-
5025-
private void resetFgsRestrictionLocked(ServiceRecord r) {
5026-
r.mAllowWhileInUsePermissionInFgs = false;
5027-
}
50284963
}

services/core/java/com/android/server/am/ActivityManagerConstants.java

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ final class ActivityManagerConstants extends ContentObserver {
8787
static final String KEY_PROCESS_START_ASYNC = "process_start_async";
8888
static final String KEY_MEMORY_INFO_THROTTLE_TIME = "memory_info_throttle_time";
8989
static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration";
90-
static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout";
9190
static final String KEY_PENDINGINTENT_WARNING_THRESHOLD = "pendingintent_warning_threshold";
9291

9392
private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
@@ -121,7 +120,6 @@ final class ActivityManagerConstants extends ContentObserver {
121120
private static final boolean DEFAULT_PROCESS_START_ASYNC = true;
122121
private static final long DEFAULT_MEMORY_INFO_THROTTLE_TIME = 5*60*1000;
123122
private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000;
124-
private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000;
125123
private static final int DEFAULT_PENDINGINTENT_WARNING_THRESHOLD = 2000;
126124

127125
// Flag stored in the DeviceConfig API.
@@ -274,12 +272,6 @@ final class ActivityManagerConstants extends ContentObserver {
274272
// this long.
275273
public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION;
276274

277-
/**
278-
* When service started from background, before the timeout it can be promoted to FGS by calling
279-
* Service.startForeground().
280-
*/
281-
volatile long mFgsStartForegroundTimeoutMs = DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS;
282-
283275
// Indicates whether the activity starts logging is enabled.
284276
// Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
285277
volatile boolean mFlagActivityStartsLoggingEnabled;
@@ -423,9 +415,6 @@ public void onPropertiesChanged(Properties properties) {
423415
case KEY_MIN_ASSOC_LOG_DURATION:
424416
updateMinAssocLogDuration();
425417
break;
426-
case KEY_FGS_START_FOREGROUND_TIMEOUT:
427-
updateFgsStartForegroundTimeout();
428-
break;
429418
default:
430419
break;
431420
}
@@ -698,13 +687,6 @@ private void updateMinAssocLogDuration() {
698687
/* defaultValue */ DEFAULT_MIN_ASSOC_LOG_DURATION);
699688
}
700689

701-
private void updateFgsStartForegroundTimeout() {
702-
mFgsStartForegroundTimeoutMs = DeviceConfig.getLong(
703-
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
704-
KEY_FGS_START_FOREGROUND_TIMEOUT,
705-
DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS);
706-
}
707-
708690
void dump(PrintWriter pw) {
709691
pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
710692
+ Settings.Global.ACTIVITY_MANAGER_CONSTANTS + ":");
@@ -777,8 +759,6 @@ void dump(PrintWriter pw) {
777759
pw.println(Arrays.toString(IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.toArray()));
778760
pw.print(" "); pw.print(KEY_MIN_ASSOC_LOG_DURATION); pw.print("=");
779761
pw.println(MIN_ASSOC_LOG_DURATION);
780-
pw.print(" "); pw.print(KEY_FGS_START_FOREGROUND_TIMEOUT); pw.print("=");
781-
pw.println(mFgsStartForegroundTimeoutMs);
782762

783763
pw.println();
784764
if (mOverrideMaxCachedProcesses >= 0) {

services/core/java/com/android/server/am/ServiceRecord.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
138138
// allow while-in-use permissions in foreground service or not.
139139
// while-in-use permissions in FGS started from background might be restricted.
140140
boolean mAllowWhileInUsePermissionInFgs;
141-
// The number of times Service.startForeground() is called;
142-
int mStartForegroundCount;
143-
// Last time mAllowWhileInUsePermissionInFgs is set.
144-
long mLastSetFgsRestrictionTime;
145141

146142
// the most recent package that start/bind this service.
147143
String mRecentCallingPackage;
@@ -404,8 +400,6 @@ void dump(PrintWriter pw, String prefix) {
404400
}
405401
pw.print(prefix); pw.print("allowWhileInUsePermissionInFgs=");
406402
pw.println(mAllowWhileInUsePermissionInFgs);
407-
pw.print(prefix); pw.print("startForegroundCount=");
408-
pw.println(mStartForegroundCount);
409403
pw.print(prefix); pw.print("recentCallingPackage=");
410404
pw.println(mRecentCallingPackage);
411405
if (delayed) {

0 commit comments

Comments
 (0)