Merge "[ipsec-qtaguid] Tag sockets upon creation of encap sockets"

This commit is contained in:
Benedict Wong
2017-12-18 23:50:52 +00:00
committed by Gerrit Code Review
2 changed files with 67 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ package android.net;
import android.annotation.RequiresPermission; import android.annotation.RequiresPermission;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.DownloadManager; import android.app.DownloadManager;
import android.app.backup.BackupManager; import android.app.backup.BackupManager;
import android.app.usage.NetworkStatsManager; import android.app.usage.NetworkStatsManager;
@@ -154,6 +155,8 @@ public class TrafficStats {
private static Object sProfilingLock = new Object(); private static Object sProfilingLock = new Object();
private static final String LOOPBACK_IFACE = "lo";
/** /**
* Set active tag to use when accounting {@link Socket} traffic originating * Set active tag to use when accounting {@link Socket} traffic originating
* from the current thread. Only one active tag per thread is supported. * from the current thread. Only one active tag per thread is supported.
@@ -542,6 +545,30 @@ public class TrafficStats {
return nativeGetIfaceStat(iface, TYPE_RX_BYTES); return nativeGetIfaceStat(iface, TYPE_RX_BYTES);
} }
/** {@hide} */
@TestApi
public static long getLoopbackTxPackets() {
return nativeGetIfaceStat(LOOPBACK_IFACE, TYPE_TX_PACKETS);
}
/** {@hide} */
@TestApi
public static long getLoopbackRxPackets() {
return nativeGetIfaceStat(LOOPBACK_IFACE, TYPE_RX_PACKETS);
}
/** {@hide} */
@TestApi
public static long getLoopbackTxBytes() {
return nativeGetIfaceStat(LOOPBACK_IFACE, TYPE_TX_BYTES);
}
/** {@hide} */
@TestApi
public static long getLoopbackRxBytes() {
return nativeGetIfaceStat(LOOPBACK_IFACE, TYPE_RX_BYTES);
}
/** /**
* Return number of packets transmitted since device boot. Counts packets * Return number of packets transmitted since device boot. Counts packets
* across all network interfaces, and always increases monotonically since * across all network interfaces, and always increases monotonically since

View File

@@ -34,6 +34,7 @@ import android.net.IpSecTransform;
import android.net.IpSecTransformResponse; import android.net.IpSecTransformResponse;
import android.net.IpSecUdpEncapResponse; import android.net.IpSecUdpEncapResponse;
import android.net.NetworkUtils; import android.net.NetworkUtils;
import android.net.TrafficStats;
import android.net.util.NetdService; import android.net.util.NetdService;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
@@ -120,6 +121,7 @@ public class IpSecService extends IIpSecService.Stub {
} }
private final IpSecServiceConfiguration mSrvConfig; private final IpSecServiceConfiguration mSrvConfig;
final UidFdTagger mUidFdTagger;
/** /**
* Interface for user-reference and kernel-resource cleanup. * Interface for user-reference and kernel-resource cleanup.
@@ -762,8 +764,23 @@ public class IpSecService extends IIpSecService.Stub {
/** @hide */ /** @hide */
@VisibleForTesting @VisibleForTesting
public IpSecService(Context context, IpSecServiceConfiguration config) { public IpSecService(Context context, IpSecServiceConfiguration config) {
this(context, config, (fd, uid) -> {
try{
TrafficStats.setThreadStatsUid(uid);
TrafficStats.tagFileDescriptor(fd);
} finally {
TrafficStats.clearThreadStatsUid();
}
});
}
/** @hide */
@VisibleForTesting
public IpSecService(
Context context, IpSecServiceConfiguration config, UidFdTagger uidFdTagger) {
mContext = context; mContext = context;
mSrvConfig = config; mSrvConfig = config;
mUidFdTagger = uidFdTagger;
} }
public void systemReady() { public void systemReady() {
@@ -924,6 +941,26 @@ public class IpSecService extends IIpSecService.Stub {
throw new IOException("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port"); throw new IOException("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port");
} }
/**
* Functional interface to do traffic tagging of given sockets to UIDs.
*
* <p>Specifically used by openUdpEncapsulationSocket to ensure data usage on the UDP encap
* sockets are billed to the UID that the UDP encap socket was created on behalf of.
*
* <p>Separate class so that the socket tagging logic can be mocked; TrafficStats uses static
* methods that cannot be easily mocked/tested.
*/
@VisibleForTesting
public interface UidFdTagger {
/**
* Sets socket tag to assign all traffic to the provided UID.
*
* <p>Since the socket is created on behalf of an unprivileged application, all traffic
* should be accounted to the UID of the unprivileged application.
*/
public void tag(FileDescriptor fd, int uid) throws IOException;
}
/** /**
* Open a socket via the system server and bind it to the specified port (random if port=0). * Open a socket via the system server and bind it to the specified port (random if port=0).
* This will return a PFD to the user that represent a bound UDP socket. The system server will * This will return a PFD to the user that represent a bound UDP socket. The system server will
@@ -939,7 +976,8 @@ public class IpSecService extends IIpSecService.Stub {
} }
checkNotNull(binder, "Null Binder passed to openUdpEncapsulationSocket"); checkNotNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid()); int callingUid = Binder.getCallingUid();
UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
int resourceId = mNextResourceId.getAndIncrement(); int resourceId = mNextResourceId.getAndIncrement();
FileDescriptor sockFd = null; FileDescriptor sockFd = null;
try { try {
@@ -948,6 +986,7 @@ public class IpSecService extends IIpSecService.Stub {
} }
sockFd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sockFd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
mUidFdTagger.tag(sockFd, callingUid);
if (port != 0) { if (port != 0) {
Log.v(TAG, "Binding to port " + port); Log.v(TAG, "Binding to port " + port);