Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78cd384e authored by Chenbo Feng's avatar Chenbo Feng Committed by junyulai
Browse files

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
parent cde07e5d
Loading
Loading
Loading
Loading
+16 −44
Original line number Diff line number Diff line
@@ -775,18 +775,11 @@ 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;
        }
    }

    /**
@@ -808,18 +801,11 @@ 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;
        }
    }

    /**
@@ -841,18 +827,11 @@ 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;
        }
    }

    /**
@@ -874,18 +853,11 @@ 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;
        }
    }

    /**
+5 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.NetworkTemplate.getCollapsedRatType;
import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.TrafficStats.UNSUPPORTED;
import static android.os.Trace.TRACE_TAG_NETWORK;
import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
import static android.provider.Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED;
@@ -1021,6 +1022,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {

    @Override
    public long getUidStats(int uid, int type) {
        final int callingUid = Binder.getCallingUid();
        if (callingUid != android.os.Process.SYSTEM_UID && callingUid != uid) {
            return UNSUPPORTED;
        }
        return nativeGetUidStat(uid, type, checkBpfStatsEnable());
    }