TransportInfo: Add a generic redaction mechanism

This replaces the existing mechanism for redacting location sensitive
fields with a more extensible mechanism. Currently supported redactions
are for the following permissions:
i. ACCESS_FINE_LOCATION
ii. LOCAL_MAC_ADDRESS
iii. NETWORK_SETTINGS

Also, removed WifiInfo from ConnectivityServiceTest to reduce cross
dependencies on wifi code.

Bug: 156867433
Bug: 162602799
Test: atest android.net
Test: atest com.android.server
Change-Id: I2bb980c624667a55c1383f13ab71b9b97ed6eeab
This commit is contained in:
Roshan Pius
2021-02-23 08:47:39 -08:00
parent c2ea3ab97d
commit 98f59ecb99
8 changed files with 570 additions and 171 deletions

View File

@@ -27,7 +27,13 @@ package android.net {
}
public final class NetworkCapabilities implements android.os.Parcelable {
ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, long);
method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L
field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L
field public static final long REDACT_FOR_NETWORK_SETTINGS = 4L; // 0x4L
field public static final long REDACT_NONE = 0L; // 0x0L
field public static final int TRANSPORT_TEST = 7; // 0x7
}
@@ -79,6 +85,11 @@ package android.net {
field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
}
public interface TransportInfo {
method public default long getApplicableRedactions();
method @NonNull public default android.net.TransportInfo makeCopy(long);
}
public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
ctor public VpnTransportInfo(int);
method public int describeContents();

View File

@@ -263,7 +263,6 @@ package android.net {
}
public final class NetworkCapabilities implements android.os.Parcelable {
ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, boolean);
method @NonNull public int[] getAdministratorUids();
method @Nullable public String getSsid();
method @NonNull public int[] getTransportTypes();
@@ -437,11 +436,6 @@ package android.net {
field public final int tcpWindowScale;
}
public interface TransportInfo {
method public default boolean hasLocationSensitiveFields();
method @NonNull public default android.net.TransportInfo makeCopy(boolean);
}
}
package android.net.apf {

View File

@@ -434,7 +434,7 @@ public abstract class NetworkAgent {
}
mInitialConfiguration = new InitialConfiguration(context,
new NetworkCapabilities(nc, /* parcelLocationSensitiveFields */ true),
new NetworkCapabilities(nc, NetworkCapabilities.REDACT_NONE),
new LinkProperties(lp), score, config, ni);
}
@@ -878,8 +878,7 @@ public abstract class NetworkAgent {
mBandwidthUpdatePending.set(false);
mLastBwRefreshTime = System.currentTimeMillis();
final NetworkCapabilities nc =
new NetworkCapabilities(networkCapabilities,
/* parcelLocationSensitiveFields */ true);
new NetworkCapabilities(networkCapabilities, NetworkCapabilities.REDACT_NONE);
queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
}

View File

@@ -19,6 +19,7 @@ package android.net;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
import android.annotation.IntDef;
import android.annotation.LongDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -65,6 +66,68 @@ import java.util.StringJoiner;
public final class NetworkCapabilities implements Parcelable {
private static final String TAG = "NetworkCapabilities";
/**
* Mechanism to support redaction of fields in NetworkCapabilities that are guarded by specific
* app permissions.
**/
/**
* Don't redact any fields since the receiving app holds all the necessary permissions.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final long REDACT_NONE = 0;
/**
* Redact any fields that need {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
* permission since the receiving app does not hold this permission or the location toggle
* is off.
*
* @see android.Manifest.permission#ACCESS_FINE_LOCATION
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1 << 0;
/**
* Redact any fields that need {@link android.Manifest.permission#LOCAL_MAC_ADDRESS}
* permission since the receiving app does not hold this permission.
*
* @see android.Manifest.permission#LOCAL_MAC_ADDRESS
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 1 << 1;
/**
*
* Redact any fields that need {@link android.Manifest.permission#NETWORK_SETTINGS}
* permission since the receiving app does not hold this permission.
*
* @see android.Manifest.permission#NETWORK_SETTINGS
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final long REDACT_FOR_NETWORK_SETTINGS = 1 << 2;
/**
* Redact all fields in this object that require any relevant permission.
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final long REDACT_ALL = -1L;
/** @hide */
@LongDef(flag = true, prefix = { "REDACT_" }, value = {
REDACT_NONE,
REDACT_FOR_ACCESS_FINE_LOCATION,
REDACT_FOR_LOCAL_MAC_ADDRESS,
REDACT_FOR_NETWORK_SETTINGS,
REDACT_ALL
})
@Retention(RetentionPolicy.SOURCE)
public @interface RedactionType {}
// Set to true when private DNS is broken.
private boolean mPrivateDnsBroken;
@@ -79,32 +142,31 @@ public final class NetworkCapabilities implements Parcelable {
private String mRequestorPackageName;
/**
* Indicates whether parceling should preserve fields that are set based on permissions of
* the process receiving the {@link NetworkCapabilities}.
* Indicates what fields should be redacted from this instance.
*/
private final boolean mParcelLocationSensitiveFields;
private final @RedactionType long mRedactions;
public NetworkCapabilities() {
mParcelLocationSensitiveFields = false;
mRedactions = REDACT_ALL;
clearAll();
mNetworkCapabilities = DEFAULT_CAPABILITIES;
}
public NetworkCapabilities(NetworkCapabilities nc) {
this(nc, false /* parcelLocationSensitiveFields */);
this(nc, REDACT_ALL);
}
/**
* Make a copy of NetworkCapabilities.
*
* @param nc Original NetworkCapabilities
* @param parcelLocationSensitiveFields Whether to parcel location sensitive data or not.
* @param redactions bitmask of redactions that needs to be performed on this new instance of
* {@link NetworkCapabilities}.
* @hide
*/
@SystemApi
public NetworkCapabilities(
@Nullable NetworkCapabilities nc, boolean parcelLocationSensitiveFields) {
mParcelLocationSensitiveFields = parcelLocationSensitiveFields;
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public NetworkCapabilities(@Nullable NetworkCapabilities nc, @RedactionType long redactions) {
mRedactions = redactions;
if (nc != null) {
set(nc);
}
@@ -116,11 +178,13 @@ public final class NetworkCapabilities implements Parcelable {
* @hide
*/
public void clearAll() {
// Ensures that the internal copies maintained by the connectivity stack does not set
// this bit.
if (mParcelLocationSensitiveFields) {
// Ensures that the internal copies maintained by the connectivity stack does not set it to
// anything other than |REDACT_ALL|.
if (mRedactions != REDACT_ALL) {
// This is needed because the current redaction mechanism relies on redaction while
// parceling.
throw new UnsupportedOperationException(
"Cannot clear NetworkCapabilities when parcelLocationSensitiveFields is set");
"Cannot clear NetworkCapabilities when mRedactions is set");
}
mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
@@ -150,7 +214,7 @@ public final class NetworkCapabilities implements Parcelable {
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
mNetworkSpecifier = nc.mNetworkSpecifier;
if (nc.getTransportInfo() != null) {
setTransportInfo(nc.getTransportInfo().makeCopy(mParcelLocationSensitiveFields));
setTransportInfo(nc.getTransportInfo().makeCopy(mRedactions));
} else {
setTransportInfo(null);
}
@@ -2350,6 +2414,23 @@ public final class NetworkCapabilities implements Parcelable {
}
}
/**
* Returns a bitmask of all the applicable redactions (based on the permissions held by the
* receiving app) to be performed on this object.
*
* @return bitmask of redactions applicable on this instance.
* @hide
*/
public @RedactionType long getApplicableRedactions() {
// Currently, there are no fields redacted in NetworkCapabilities itself, so we just
// passthrough the redactions required by the embedded TransportInfo. If this changes
// in the future, modify this method.
if (mTransportInfo == null) {
return NetworkCapabilities.REDACT_NONE;
}
return mTransportInfo.getApplicableRedactions();
}
/**
* Builder class for NetworkCapabilities.
*

View File

@@ -29,35 +29,47 @@ import android.annotation.SystemApi;
public interface TransportInfo {
/**
* Create a copy of a {@link TransportInfo} that will preserve location sensitive fields that
* were set based on the permissions of the process that originally received it.
* Create a copy of a {@link TransportInfo} with some fields redacted based on the permissions
* held by the receiving app.
*
* <p>By default {@link TransportInfo} does not preserve such fields during parceling, as
* they should not be shared outside of the process that receives them without appropriate
* checks.
* <p>
* Usage by connectivity stack:
* <ul>
* <li> Connectivity stack will invoke {@link #getApplicableRedactions()} to find the list
* of redactions that are required by this {@link TransportInfo} instance.</li>
* <li> Connectivity stack then loops through each bit in the bitmask returned and checks if the
* receiving app holds the corresponding permission.
* <ul>
* <li> If the app holds the corresponding permission, the bit is cleared from the
* |redactions| bitmask. </li>
* <li> If the app does not hold the corresponding permission, the bit is retained in the
* |redactions| bitmask. </li>
* </ul>
* <li> Connectivity stack then invokes {@link #makeCopy(long)} with the necessary |redactions|
* to create a copy to send to the corresponding app. </li>
* </ul>
* </p>
*
* @param parcelLocationSensitiveFields Whether the location sensitive fields should be kept
* when parceling
* @return Copy of this instance.
* @param redactions bitmask of redactions that needs to be performed on this instance.
* @return Copy of this instance with the necessary redactions.
* @hide
*/
@SystemApi
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@NonNull
default TransportInfo makeCopy(boolean parcelLocationSensitiveFields) {
default TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
return this;
}
/**
* Returns whether this TransportInfo type has location sensitive fields or not (helps
* to determine whether to perform a location permission check or not before sending to
* apps).
* Returns a bitmask of all the applicable redactions (based on the permissions held by the
* receiving app) to be performed on this TransportInfo.
*
* @return {@code true} if this instance contains location sensitive info, {@code false}
* otherwise.
* @return bitmask of redactions applicable on this instance.
* @see #makeCopy(long)
* @hide
*/
@SystemApi
default boolean hasLocationSensitiveFields() {
return false;
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
default @NetworkCapabilities.RedactionType long getApplicableRedactions() {
return NetworkCapabilities.REDACT_NONE;
}
}