diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java index 060af0dd1ba1f..54e1899e9a004 100644 --- a/core/java/android/net/NetworkScoreManager.java +++ b/core/java/android/net/NetworkScoreManager.java @@ -227,6 +227,8 @@ public class NetworkScoreManager { * @return the full package name of the current active scorer, or null if there is no active * scorer. */ + @RequiresPermission(anyOf = {android.Manifest.permission.SCORE_NETWORKS, + android.Manifest.permission.REQUEST_NETWORK_SCORES}) public String getActiveScorerPackage() { try { return mService.getActiveScorerPackage(); diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index d60df83da68e2..e438620faeb77 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -640,13 +640,13 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } } - private boolean callerCanRequestScores() { + private boolean canCallerRequestScores() { // REQUEST_NETWORK_SCORES is a signature only permission. return mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES) == PackageManager.PERMISSION_GRANTED; } - private boolean callerCanScoreNetworks() { + private boolean canCallerScoreNetworks() { return mContext.checkCallingOrSelfPermission(permission.SCORE_NETWORKS) == PackageManager.PERMISSION_GRANTED; } @@ -654,7 +654,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public boolean clearScores() { // Only the active scorer or the system should be allowed to flush all scores. - if (isCallerActiveScorer(getCallingUid()) || callerCanRequestScores()) { + if (isCallerActiveScorer(getCallingUid()) || canCallerRequestScores()) { final long token = Binder.clearCallingIdentity(); try { clearInternal(); @@ -671,7 +671,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public boolean setActiveScorer(String packageName) { // Only the system can set the active scorer - if (!isCallerSystemProcess(getCallingUid()) && !callerCanScoreNetworks()) { + if (!isCallerSystemProcess(getCallingUid()) && !canCallerScoreNetworks()) { throw new SecurityException( "Caller is neither the system process or a network scorer."); } @@ -705,11 +705,17 @@ public class NetworkScoreService extends INetworkScoreService.Stub { */ @Override public String getActiveScorerPackage() { - synchronized (mServiceConnectionLock) { - if (mServiceConnection != null) { - return mServiceConnection.getPackageName(); + if (canCallerRequestScores() || canCallerScoreNetworks()) { + synchronized (mServiceConnectionLock) { + if (mServiceConnection != null) { + return mServiceConnection.getPackageName(); + } } + } else { + throw new SecurityException( + "Caller is not a network scorer/requester."); } + return null; } @@ -719,7 +725,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public NetworkScorerAppData getActiveScorer() { // Only the system can access this data. - if (isCallerSystemProcess(getCallingUid()) || callerCanRequestScores()) { + if (isCallerSystemProcess(getCallingUid()) || canCallerRequestScores()) { synchronized (mServiceConnectionLock) { if (mServiceConnection != null) { return mServiceConnection.getAppData(); @@ -740,7 +746,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public List getAllValidScorers() { // Only the system can access this data. - if (!isCallerSystemProcess(getCallingUid()) && !callerCanRequestScores()) { + if (!isCallerSystemProcess(getCallingUid()) && !canCallerRequestScores()) { throw new SecurityException( "Caller is neither the system process nor a score requester."); } @@ -751,7 +757,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public void disableScoring() { // Only the active scorer or the system should be allowed to disable scoring. - if (!isCallerActiveScorer(getCallingUid()) && !callerCanRequestScores()) { + if (!isCallerActiveScorer(getCallingUid()) && !canCallerRequestScores()) { throw new SecurityException( "Caller is neither the active scorer nor the scorer manager."); } diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java index bb7e20bcb9c39..be6a1a5d15b04 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java @@ -56,13 +56,11 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiSsid; import android.os.Binder; -import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; -import android.os.RemoteCallback; import android.os.RemoteException; import android.os.UserHandle; import android.support.test.InstrumentationRegistry; @@ -517,6 +515,49 @@ public class NetworkScoreServiceTest { verify(mServiceConnection).getPackageName(); } + @Test + public void testGetActiveScorerPackage_missingRequiredPermissions() throws Exception { + when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) + .thenReturn(PackageManager.PERMISSION_DENIED); + when(mContext.checkCallingOrSelfPermission(permission.SCORE_NETWORKS)) + .thenReturn(PackageManager.PERMISSION_DENIED); + + try { + mNetworkScoreService.getActiveScorerPackage(); + fail("SecurityException expected"); + } catch (SecurityException e) { + // expected + } + } + + @Test + public void testGetActiveScorerPackage_noRequestScoresPermission() throws Exception { + when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) + .thenReturn(PackageManager.PERMISSION_DENIED); + when(mContext.checkCallingOrSelfPermission(permission.SCORE_NETWORKS)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + + try { + mNetworkScoreService.getActiveScorerPackage(); + } catch (SecurityException e) { + fail("Unexpected SecurityException"); + } + } + + @Test + public void testGetActiveScorerPackage_noScoreNetworksPermission() throws Exception { + when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + when(mContext.checkCallingOrSelfPermission(permission.SCORE_NETWORKS)) + .thenReturn(PackageManager.PERMISSION_DENIED); + + try { + mNetworkScoreService.getActiveScorerPackage(); + } catch (SecurityException e) { + fail("Unexpected SecurityException"); + } + } + @Test public void testCacheUpdatingConsumer_nullFilter() throws Exception { List scoredNetworkList = Lists.newArrayList(SCORED_NETWORK);