Merge "StrictMode to detect untagged network traffic."
This commit is contained in:
@@ -24497,6 +24497,7 @@ package android.net {
|
||||
public class TrafficStats {
|
||||
ctor public TrafficStats();
|
||||
method public static void clearThreadStatsTag();
|
||||
method public static int getAndSetThreadStatsTag(int);
|
||||
method public static long getMobileRxBytes();
|
||||
method public static long getMobileRxPackets();
|
||||
method public static long getMobileTxBytes();
|
||||
@@ -30078,6 +30079,7 @@ package android.os {
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedClosableObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedRegistrationObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectUntaggedSockets();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeath();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnCleartextNetwork();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnFileUriExposure();
|
||||
|
||||
@@ -26484,6 +26484,7 @@ package android.net {
|
||||
ctor public TrafficStats();
|
||||
method public static void clearThreadStatsTag();
|
||||
method public static void clearThreadStatsUid();
|
||||
method public static int getAndSetThreadStatsTag(int);
|
||||
method public static long getMobileRxBytes();
|
||||
method public static long getMobileRxPackets();
|
||||
method public static long getMobileTxBytes();
|
||||
@@ -32730,6 +32731,7 @@ package android.os {
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedClosableObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedRegistrationObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectUntaggedSockets();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeath();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnCleartextNetwork();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnFileUriExposure();
|
||||
|
||||
@@ -24587,6 +24587,7 @@ package android.net {
|
||||
public class TrafficStats {
|
||||
ctor public TrafficStats();
|
||||
method public static void clearThreadStatsTag();
|
||||
method public static int getAndSetThreadStatsTag(int);
|
||||
method public static long getMobileRxBytes();
|
||||
method public static long getMobileRxPackets();
|
||||
method public static long getMobileTxBytes();
|
||||
@@ -30190,6 +30191,7 @@ package android.os {
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedClosableObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedRegistrationObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects();
|
||||
method public android.os.StrictMode.VmPolicy.Builder detectUntaggedSockets();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeath();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnCleartextNetwork();
|
||||
method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnFileUriExposure();
|
||||
|
||||
@@ -96,6 +96,7 @@ public class SntpClient {
|
||||
|
||||
public boolean requestTime(InetAddress address, int port, int timeout) {
|
||||
DatagramSocket socket = null;
|
||||
final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_NTP);
|
||||
try {
|
||||
socket = new DatagramSocket();
|
||||
socket.setSoTimeout(timeout);
|
||||
@@ -161,6 +162,7 @@ public class SntpClient {
|
||||
if (socket != null) {
|
||||
socket.close();
|
||||
}
|
||||
TrafficStats.setThreadStatsTag(oldTag);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -166,6 +166,24 @@ public class TrafficStats {
|
||||
NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set active tag to use when accounting {@link Socket} traffic originating
|
||||
* from the current thread. Only one active tag per thread is supported.
|
||||
* <p>
|
||||
* Changes only take effect during subsequent calls to
|
||||
* {@link #tagSocket(Socket)}.
|
||||
* <p>
|
||||
* Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
|
||||
* used internally by system services like {@link DownloadManager} when
|
||||
* performing traffic on behalf of an application.
|
||||
*
|
||||
* @return the current tag for the calling thread, which can be used to
|
||||
* restore any existing values after a nested operation is finished
|
||||
*/
|
||||
public static int getAndSetThreadStatsTag(int tag) {
|
||||
return NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set active tag to use when accounting {@link Socket} traffic originating
|
||||
* from the current thread. The tag used internally is well-defined to
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.net.TrafficStats;
|
||||
import android.net.Uri;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
@@ -245,11 +246,17 @@ public final class StrictMode {
|
||||
*/
|
||||
private static final int DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION = 0x80 << 8; // for VmPolicy
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
private static final int DETECT_VM_UNTAGGED_SOCKET = 0x80 << 24; // for VmPolicy
|
||||
|
||||
private static final int ALL_VM_DETECT_BITS =
|
||||
DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS |
|
||||
DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS |
|
||||
DETECT_VM_REGISTRATION_LEAKS | DETECT_VM_FILE_URI_EXPOSURE |
|
||||
DETECT_VM_CLEARTEXT_NETWORK | DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION;
|
||||
DETECT_VM_CLEARTEXT_NETWORK | DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION |
|
||||
DETECT_VM_UNTAGGED_SOCKET;
|
||||
|
||||
// Byte 3: Penalty
|
||||
|
||||
@@ -300,6 +307,8 @@ public final class StrictMode {
|
||||
*/
|
||||
public static final int PENALTY_DEATH_ON_FILE_URI_EXPOSURE = 0x04 << 24;
|
||||
|
||||
// CAUTION: we started stealing the top bits of Byte 4 for VM above
|
||||
|
||||
/**
|
||||
* Mask of all the penalty bits valid for thread policies.
|
||||
*/
|
||||
@@ -715,7 +724,8 @@ public final class StrictMode {
|
||||
public Builder detectAll() {
|
||||
int flags = DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS
|
||||
| DETECT_VM_CLOSABLE_LEAKS | DETECT_VM_REGISTRATION_LEAKS
|
||||
| DETECT_VM_FILE_URI_EXPOSURE | DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION;
|
||||
| DETECT_VM_FILE_URI_EXPOSURE | DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION
|
||||
| DETECT_VM_UNTAGGED_SOCKET;
|
||||
|
||||
// TODO: always add DETECT_VM_CLEARTEXT_NETWORK once we have facility
|
||||
// for apps to mark sockets that should be ignored
|
||||
@@ -819,6 +829,22 @@ public final class StrictMode {
|
||||
return enable(DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect any sockets in the calling app which have not been tagged
|
||||
* using {@link TrafficStats}. Tagging sockets can help you
|
||||
* investigate network usage inside your app, such as a narrowing
|
||||
* down heavy usage to a specific library or component.
|
||||
* <p>
|
||||
* This currently does not detect sockets created in native code.
|
||||
*
|
||||
* @see TrafficStats#setThreadStatsTag(int)
|
||||
* @see TrafficStats#tagSocket(java.net.Socket)
|
||||
* @see TrafficStats#tagDatagramSocket(java.net.DatagramSocket)
|
||||
*/
|
||||
public Builder detectUntaggedSockets() {
|
||||
return enable(DETECT_VM_UNTAGGED_SOCKET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crashes the whole process on violation. This penalty runs at the
|
||||
* end of all enabled penalties so you'll still get your logging or
|
||||
@@ -1152,6 +1178,11 @@ public final class StrictMode {
|
||||
if (IS_ENG_BUILD) {
|
||||
policyBuilder.penaltyLog();
|
||||
}
|
||||
// All core system components need to tag their sockets to aid
|
||||
// system health investigations
|
||||
if (android.os.Process.myUid() < android.os.Process.FIRST_APPLICATION_UID) {
|
||||
policyBuilder.detectUntaggedSockets();
|
||||
}
|
||||
setVmPolicy(policyBuilder.build());
|
||||
setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
|
||||
}
|
||||
@@ -1829,6 +1860,13 @@ public final class StrictMode {
|
||||
return (sVmPolicyMask & DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static boolean vmUntaggedSocketEnabled() {
|
||||
return (sVmPolicyMask & DETECT_VM_UNTAGGED_SOCKET) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -1911,6 +1949,14 @@ public final class StrictMode {
|
||||
forceDeath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static void onUntaggedSocket() {
|
||||
onVmPolicyViolation(null, new Throwable("Untagged socket detected; use"
|
||||
+ " TrafficStats.setThreadSocketTag() to track all network usage"));
|
||||
}
|
||||
|
||||
// Map from VM violation fingerprint to uptime millis.
|
||||
private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>();
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import android.os.StrictMode;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -50,16 +51,20 @@ public final class NetworkManagementSocketTagger extends SocketTagger {
|
||||
SocketTagger.set(new NetworkManagementSocketTagger());
|
||||
}
|
||||
|
||||
public static void setThreadSocketStatsTag(int tag) {
|
||||
public static int setThreadSocketStatsTag(int tag) {
|
||||
final int old = threadSocketTags.get().statsTag;
|
||||
threadSocketTags.get().statsTag = tag;
|
||||
return old;
|
||||
}
|
||||
|
||||
public static int getThreadSocketStatsTag() {
|
||||
return threadSocketTags.get().statsTag;
|
||||
}
|
||||
|
||||
public static void setThreadSocketStatsUid(int uid) {
|
||||
public static int setThreadSocketStatsUid(int uid) {
|
||||
final int old = threadSocketTags.get().statsUid;
|
||||
threadSocketTags.get().statsUid = uid;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,6 +74,9 @@ public final class NetworkManagementSocketTagger extends SocketTagger {
|
||||
Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x"
|
||||
+ Integer.toHexString(options.statsTag) + ", statsUid=" + options.statsUid);
|
||||
}
|
||||
if (options.statsTag == -1 && StrictMode.vmUntaggedSocketEnabled()) {
|
||||
StrictMode.onUntaggedSocket();
|
||||
}
|
||||
// TODO: skip tagging when options would be no-op
|
||||
tagSocketFd(fd, options.statsTag, options.statsUid);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkUtils;
|
||||
import android.net.RouteInfo;
|
||||
import android.net.TrafficStats;
|
||||
import android.os.SystemClock;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
@@ -381,7 +382,12 @@ public class NetworkDiagnostics {
|
||||
protected void setupSocket(
|
||||
int sockType, int protocol, long writeTimeout, long readTimeout, int dstPort)
|
||||
throws ErrnoException, IOException {
|
||||
mFileDescriptor = Os.socket(mAddressFamily, sockType, protocol);
|
||||
final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
|
||||
try {
|
||||
mFileDescriptor = Os.socket(mAddressFamily, sockType, protocol);
|
||||
} finally {
|
||||
TrafficStats.setThreadStatsTag(oldTag);
|
||||
}
|
||||
// Setting SNDTIMEO is purely for defensive purposes.
|
||||
Os.setsockoptTimeval(mFileDescriptor,
|
||||
SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(writeTimeout));
|
||||
|
||||
@@ -779,6 +779,7 @@ public class NetworkMonitor extends StateMachine {
|
||||
int httpResponseCode = 599;
|
||||
String redirectUrl = null;
|
||||
final Stopwatch probeTimer = new Stopwatch().start();
|
||||
final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
|
||||
try {
|
||||
urlConnection = (HttpURLConnection) mNetworkAgentInfo.network.openConnection(url);
|
||||
urlConnection.setInstanceFollowRedirects(probeType == ValidationProbeEvent.PROBE_PAC);
|
||||
@@ -839,6 +840,7 @@ public class NetworkMonitor extends StateMachine {
|
||||
if (urlConnection != null) {
|
||||
urlConnection.disconnect();
|
||||
}
|
||||
TrafficStats.setThreadStatsTag(oldTag);
|
||||
}
|
||||
logValidationProbe(probeTimer.stop(), probeType, httpResponseCode);
|
||||
return new CaptivePortalProbeResult(httpResponseCode, redirectUrl, url.toString());
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.net.ProxyInfo;
|
||||
import android.net.TrafficStats;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@@ -103,11 +104,15 @@ public class PacManager {
|
||||
String file;
|
||||
synchronized (mProxyLock) {
|
||||
if (Uri.EMPTY.equals(mPacUrl)) return;
|
||||
final int oldTag = TrafficStats
|
||||
.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PAC);
|
||||
try {
|
||||
file = get(mPacUrl);
|
||||
} catch (IOException ioe) {
|
||||
file = null;
|
||||
Log.w(TAG, "Failed to load PAC file: " + ioe);
|
||||
} finally {
|
||||
TrafficStats.setThreadStatsTag(oldTag);
|
||||
}
|
||||
}
|
||||
if (file != null) {
|
||||
|
||||
@@ -16,22 +16,19 @@
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import android.net.TrafficStats;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import libcore.io.Streams;
|
||||
|
||||
/**
|
||||
* A class for downloading GPS XTRA data.
|
||||
*
|
||||
@@ -94,7 +91,12 @@ public class GpsXtraDownloader {
|
||||
|
||||
// load balance our requests among the available servers
|
||||
while (result == null) {
|
||||
result = doDownload(mXtraServers[mNextServerIndex]);
|
||||
final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_GPS);
|
||||
try {
|
||||
result = doDownload(mXtraServers[mNextServerIndex]);
|
||||
} finally {
|
||||
TrafficStats.setThreadStatsTag(oldTag);
|
||||
}
|
||||
|
||||
// increment mNextServerIndex and wrap around if necessary
|
||||
mNextServerIndex++;
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.net.DhcpResults;
|
||||
import android.net.InterfaceConfiguration;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.NetworkUtils;
|
||||
import android.net.TrafficStats;
|
||||
import android.net.metrics.IpConnectivityLog;
|
||||
import android.net.metrics.DhcpClientEvent;
|
||||
import android.net.metrics.DhcpErrorEvent;
|
||||
@@ -303,6 +304,7 @@ public class DhcpClient extends StateMachine {
|
||||
}
|
||||
|
||||
private boolean initUdpSocket() {
|
||||
final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_DHCP);
|
||||
try {
|
||||
mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
@@ -314,6 +316,8 @@ public class DhcpClient extends StateMachine {
|
||||
} catch(SocketException|ErrnoException e) {
|
||||
Log.e(TAG, "Error creating UDP socket", e);
|
||||
return false;
|
||||
} finally {
|
||||
TrafficStats.setThreadStatsTag(oldTag);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.net.IpPrefix;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkUtils;
|
||||
import android.net.TrafficStats;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.system.StructGroupReq;
|
||||
@@ -563,6 +564,7 @@ public class RouterAdvertisementDaemon {
|
||||
private boolean createSocket() {
|
||||
final int SEND_TIMEOUT_MS = 300;
|
||||
|
||||
final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_NEIGHBOR);
|
||||
try {
|
||||
mSocket = Os.socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
|
||||
// Setting SNDTIMEO is purely for defensive purposes.
|
||||
@@ -574,6 +576,8 @@ public class RouterAdvertisementDaemon {
|
||||
} catch (ErrnoException | IOException e) {
|
||||
Log.e(TAG, "Failed to create RA daemon socket: " + e);
|
||||
return false;
|
||||
} finally {
|
||||
TrafficStats.setThreadStatsTag(oldTag);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user