Merge "Move uidPermissionMap dump to BpfNetMaps"

This commit is contained in:
Motomu Utsumi 2022-10-05 04:07:46 +00:00 • committed by Gerrit Code Review
commit bd4a2d0cee
5 changed files with 82 additions and 24 deletions

View file

@ -717,21 +717,6 @@ void TrafficController::dump(int fd, bool verbose) {
if (!res.ok()) {
dw.println("mUidOwnerMap print end with error: %s", res.error().message().c_str());
}
dumpBpfMap("mUidPermissionMap", dw, "");
const auto printUidPermissionInfo = [&dw](const uint32_t& key, const int& value,
const BpfMap<uint32_t, uint8_t>&) {
dw.println("%u %s", key, UidPermissionTypeToString(value).c_str());
return base::Result<void>();
};
res = mUidPermissionMap.iterateWithValue(printUidPermissionInfo);
if (!res.ok()) {
dw.println("mUidPermissionMap print end with error: %s", res.error().message().c_str());
}
dumpBpfMap("mPrivilegedUser", dw, "");
for (uid_t uid : mPrivilegedUser) {
dw.println("%u ALLOW_UPDATE_DEVICE_STATS", (uint32_t)uid);
}
}
} // namespace net

View file

@ -798,11 +798,6 @@ TEST_F(TrafficControllerTest, TestDumpsys) {
expectedLines.emplace_back("mUidOwnerMap:");
expectedLines.emplace_back(fmt::format("{} HAPPY_BOX_MATCH", TEST_UID));
mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, {TEST_UID2});
expectedLines.emplace_back("mUidPermissionMap:");
expectedLines.emplace_back(fmt::format("{} BPF_PERMISSION_UPDATE_DEVICE_STATS", TEST_UID2));
expectedLines.emplace_back("mPrivilegedUser:");
expectedLines.emplace_back(fmt::format("{} ALLOW_UPDATE_DEVICE_STATS", TEST_UID2));
EXPECT_TRUE(expectDumpsysContains(expectedLines));
}
@ -821,8 +816,7 @@ TEST_F(TrafficControllerTest, dumpsysInvalidMaps) {
fmt::format("mIfaceStatsMap {}", kErrIterate),
fmt::format("mConfigurationMap {}", kErrReadRulesConfig),
fmt::format("mConfigurationMap {}", kErrReadStatsMapConfig),
fmt::format("mUidOwnerMap {}", kErrIterate),
fmt::format("mUidPermissionMap {}", kErrIterate)};
fmt::format("mUidOwnerMap {}", kErrIterate)};
EXPECT_TRUE(expectDumpsysContains(expectedLines));
}

View file

@ -27,7 +27,9 @@ import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
import static android.net.INetd.PERMISSION_INTERNET;
import static android.net.INetd.PERMISSION_NONE;
import static android.net.INetd.PERMISSION_UNINSTALLED;
import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
import static android.system.OsConstants.EINVAL;
import static android.system.OsConstants.ENODEV;
import static android.system.OsConstants.ENOENT;
@ -44,12 +46,15 @@ import android.provider.DeviceConfig;
import android.system.ErrnoException;
import android.system.Os;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Pair;
import android.util.StatsEvent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.BackgroundThread;
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BpfDump;
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.DeviceConfigUtils;
import com.android.net.module.util.IBpfMap;
@ -62,8 +67,10 @@ import com.android.net.module.util.bpf.CookieTagMapValue;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
/**
* BpfNetMaps is responsible for providing traffic controller relevant functionality.
@ -134,6 +141,11 @@ public class BpfNetMaps {
@VisibleForTesting public static final long OEM_DENY_3_MATCH = (1 << 11);
// LINT.ThenChange(packages/modules/Connectivity/bpf_progs/bpf_shared.h)
private static final List<Pair<Integer, String>> PERMISSION_LIST = Arrays.asList(
Pair.create(PERMISSION_INTERNET, "PERMISSION_INTERNET"),
Pair.create(PERMISSION_UPDATE_DEVICE_STATS, "PERMISSION_UPDATE_DEVICE_STATS")
);
/**
* Set sEnableJavaBpfMap for test.
*/
@ -914,14 +926,40 @@ public class BpfNetMaps {
return StatsManager.PULL_SUCCESS;
}
private String permissionToString(int permissionMask) {
if (permissionMask == PERMISSION_NONE) {
return "PERMISSION_NONE";
}
if (permissionMask == PERMISSION_UNINSTALLED) {
// PERMISSION_UNINSTALLED should never appear in the map
return "PERMISSION_UNINSTALLED error!";
}
final StringJoiner sj = new StringJoiner(" ");
for (Pair<Integer, String> permission: PERMISSION_LIST) {
final int permissionFlag = permission.first;
final String permissionName = permission.second;
if ((permissionMask & permissionFlag) != 0) {
sj.add(permissionName);
permissionMask &= ~permissionFlag;
}
}
if (permissionMask != 0) {
sj.add("PERMISSION_UNKNOWN(" + permissionMask + ")");
}
return sj.toString();
}
/**
* Dump BPF maps
*
* @param pw print writer
* @param fd file descriptor to output
* @param verbose verbose dump flag, if true dump the BpfMap contents
* @throws IOException when file descriptor is invalid.
* @throws ServiceSpecificException when the method is called on an unsupported device.
*/
public void dump(final FileDescriptor fd, boolean verbose)
public void dump(final IndentingPrintWriter pw, final FileDescriptor fd, boolean verbose)
throws IOException, ServiceSpecificException {
if (PRE_T) {
throw new ServiceSpecificException(
@ -929,6 +967,11 @@ public class BpfNetMaps {
+ " devices, use dumpsys netd trafficcontroller instead.");
}
mDeps.nativeDump(fd, verbose);
if (verbose) {
BpfDump.dumpMap(sUidPermissionMap, pw, "sUidPermissionMap",
(uid, permission) -> uid.val + " " + permissionToString(permission.val));
}
}
private static native void native_init(boolean startSkDestroyListener);

View file

@ -3457,7 +3457,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void dumpTrafficController(IndentingPrintWriter pw, final FileDescriptor fd,
boolean verbose) {
try {
mBpfNetMaps.dump(fd, verbose);
mBpfNetMaps.dump(pw, fd, verbose);
} catch (ServiceSpecificException e) {
pw.println(e.getMessage());
} catch (IOException e) {

View file

@ -61,6 +61,7 @@ import android.net.INetd;
import android.os.Build;
import android.os.ServiceSpecificException;
import android.system.ErrnoException;
import android.util.IndentingPrintWriter;
import androidx.test.filters.SmallTest;
@ -84,6 +85,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.FileDescriptor;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
@ -927,4 +930,37 @@ public final class BpfNetMapsTest {
final int ret = mBpfNetMaps.pullBpfMapInfoAtom(-1 /* atomTag */, new ArrayList<>());
assertEquals(StatsManager.PULL_SKIP, ret);
}
private void assertDumpContains(final String dump, final String message) {
assertTrue(String.format("dump(%s) does not contain '%s'", dump, message),
dump.contains(message));
}
private String getDump() throws Exception {
final StringWriter sw = new StringWriter();
mBpfNetMaps.dump(new IndentingPrintWriter(sw), new FileDescriptor(), true /* verbose */);
return sw.toString();
}
private void doTestDumpUidPermissionMap(final int permission, final String permissionString)
throws Exception {
mUidPermissionMap.updateEntry(new S32(TEST_UID), new U8((short) permission));
assertDumpContains(getDump(), TEST_UID + " " + permissionString);
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.S_V2)
public void testDumpUidPermissionMap() throws Exception {
doTestDumpUidPermissionMap(PERMISSION_NONE, "PERMISSION_NONE");
doTestDumpUidPermissionMap(PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS,
"PERMISSION_INTERNET PERMISSION_UPDATE_DEVICE_STATS");
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.S_V2)
public void testDumpUidPermissionMapInvalidPermission() throws Exception {
doTestDumpUidPermissionMap(PERMISSION_UNINSTALLED, "PERMISSION_UNINSTALLED error!");
doTestDumpUidPermissionMap(PERMISSION_INTERNET | 1 << 6,
"PERMISSION_INTERNET PERMISSION_UNKNOWN(64)");
}
}