Enforce permission check in getUidStats function

The NetworkStatsService.getUidStats() currently doesn't have any
permission check to make sure unpriviledged apps cannot read the stats
of a different uid. It will protentially have security problem since
apps with ACCESS_NETWORK_STATS permission can directly calling into
NetworkStatsService and bypass the check in TrafficStats. Move the uid
check from TrafficStats to NetworkStatsService to fix the problem.

Bug: 129151407
Test: atest AppSecurityTests#testAppFailAccessPrivateData_full
Test: atest AppSecurityTests#testAppFailAccessPrivateData_instant
Test: atest android.app.usage.cts.NetworkUsageStatsTest
Test: atest NetworkStatsBinderTest

Change-Id: Iae85676cfe5f114da69ec278afc2c904bc907234
This commit is contained in:
Chenbo Feng
2019-06-17 16:22:28 -07:00
committed by junyulai
parent 5d0d638f54
commit d80a6ed9e2
2 changed files with 21 additions and 44 deletions

View File

@@ -775,17 +775,10 @@ public class TrafficStats {
* @see android.content.pm.ApplicationInfo#uid
*/
public static long getUidTxBytes(int uid) {
// This isn't actually enforcing any security; it just returns the
// unsupported value. The real filtering is done at the kernel level.
final int callingUid = android.os.Process.myUid();
if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) {
try {
return getStatsService().getUidStats(uid, TYPE_TX_BYTES);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} else {
return UNSUPPORTED;
try {
return getStatsService().getUidStats(uid, TYPE_TX_BYTES);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@@ -808,17 +801,10 @@ public class TrafficStats {
* @see android.content.pm.ApplicationInfo#uid
*/
public static long getUidRxBytes(int uid) {
// This isn't actually enforcing any security; it just returns the
// unsupported value. The real filtering is done at the kernel level.
final int callingUid = android.os.Process.myUid();
if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) {
try {
return getStatsService().getUidStats(uid, TYPE_RX_BYTES);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} else {
return UNSUPPORTED;
try {
return getStatsService().getUidStats(uid, TYPE_RX_BYTES);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@@ -841,17 +827,10 @@ public class TrafficStats {
* @see android.content.pm.ApplicationInfo#uid
*/
public static long getUidTxPackets(int uid) {
// This isn't actually enforcing any security; it just returns the
// unsupported value. The real filtering is done at the kernel level.
final int callingUid = android.os.Process.myUid();
if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) {
try {
return getStatsService().getUidStats(uid, TYPE_TX_PACKETS);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} else {
return UNSUPPORTED;
try {
return getStatsService().getUidStats(uid, TYPE_TX_PACKETS);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@@ -874,17 +853,10 @@ public class TrafficStats {
* @see android.content.pm.ApplicationInfo#uid
*/
public static long getUidRxPackets(int uid) {
// This isn't actually enforcing any security; it just returns the
// unsupported value. The real filtering is done at the kernel level.
final int callingUid = android.os.Process.myUid();
if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) {
try {
return getStatsService().getUidStats(uid, TYPE_RX_PACKETS);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} else {
return UNSUPPORTED;
try {
return getStatsService().getUidStats(uid, TYPE_RX_PACKETS);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}