Verify the access to the mdnsd socket is blocked from Android U

The untrusted apps should not directly access /dev/socket/mdnsd since
Android U(SDK 34). For untrusted apps built with target SDK 33 or less,
it should still be able to access the mdnsd socket. Fix the mts test
suits from mts-networking to mts-tethering. If the test suits is marked
as mts-networking, it would run in NetworkStack MTS, which isn't really
what is tested in the tests.

Test: atest CtsNetTestCases CtsNetTestCasesMaxTargetSdk33
Bug: 267102290
Change-Id: I851c181fa7489115fb1f335a369830078f5a5c14
This commit is contained in:
Yuyang Huang 2023-02-17 17:29:01 +09:00
commit 72bc600be2
3 changed files with 112 additions and 15 deletions

View file

@ -57,6 +57,17 @@
}
]
},
{
"name": "CtsNetTestCasesMaxTargetSdk33",
"options": [
{
"exclude-annotation": "com.android.testutils.SkipPresubmit"
},
{
"exclude-annotation": "androidx.test.filters.RequiresDevice"
}
]
},
{
"name": "bpf_existence_test"
},
@ -143,6 +154,17 @@
}
]
},
{
"name": "CtsNetTestCasesMaxTargetSdk33[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]",
"options": [
{
"exclude-annotation": "com.android.testutils.SkipPresubmit"
},
{
"exclude-annotation": "androidx.test.filters.RequiresDevice"
}
]
},
// Test with APK modules only, in cases where APEX is not supported, or the other modules
// were simply not updated
{

View file

@ -114,34 +114,39 @@ android_test {
],
}
android_test {
name: "CtsNetTestCasesMaxTargetSdk31", // Must match CtsNetTestCasesMaxTargetSdk31 annotation.
java_defaults {
name: "CtsNetTestCasesMaxTargetSdkDefaults",
defaults: [
"CtsNetTestCasesDefaults",
"CtsNetTestCasesApiStableDefaults",
],
target_sdk_version: "31",
package_name: "android.net.cts.maxtargetsdk31", // CTS package names must be unique.
instrumentation_target_package: "android.net.cts.maxtargetsdk31",
test_suites: [
"cts",
"general-tests",
"mts-networking",
"mts-tethering",
],
}
android_test {
name: "CtsNetTestCasesMaxTargetSdk33", // Must match CtsNetTestCasesMaxTargetSdk33 annotation.
defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"],
target_sdk_version: "33",
package_name: "android.net.cts.maxtargetsdk33",
instrumentation_target_package: "android.net.cts.maxtargetsdk33",
}
android_test {
name: "CtsNetTestCasesMaxTargetSdk31", // Must match CtsNetTestCasesMaxTargetSdk31 annotation.
defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"],
target_sdk_version: "31",
package_name: "android.net.cts.maxtargetsdk31", // CTS package names must be unique.
instrumentation_target_package: "android.net.cts.maxtargetsdk31",
}
android_test {
name: "CtsNetTestCasesMaxTargetSdk30", // Must match CtsNetTestCasesMaxTargetSdk30 annotation.
defaults: [
"CtsNetTestCasesDefaults",
"CtsNetTestCasesApiStableDefaults",
],
defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"],
target_sdk_version: "30",
package_name: "android.net.cts.maxtargetsdk30", // CTS package names must be unique.
instrumentation_target_package: "android.net.cts.maxtargetsdk30",
test_suites: [
"cts",
"general-tests",
"mts-networking",
],
}

View file

@ -20,6 +20,8 @@ import android.app.compat.CompatChanges
import android.net.ConnectivityManager
import android.net.ConnectivityManager.NetworkCallback
import android.net.LinkProperties
import android.net.LocalSocket
import android.net.LocalSocketAddress
import android.net.Network
import android.net.NetworkAgentConfig
import android.net.NetworkCapabilities
@ -63,6 +65,8 @@ import android.platform.test.annotations.AppModeFull
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
import com.android.compatibility.common.util.PollingCheck
import com.android.compatibility.common.util.PropertyUtil
import com.android.net.module.util.ArrayTrackRecord
import com.android.net.module.util.TrackRecord
import com.android.networkstack.apishim.NsdShimImpl
@ -72,14 +76,17 @@ import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.TestableNetworkAgent
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk30
import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk33
import com.android.testutils.runAsShell
import com.android.testutils.tryTest
import com.android.testutils.waitForIdle
import java.io.File
import java.io.IOException
import java.net.ServerSocket
import java.nio.charset.StandardCharsets
import java.util.Random
import java.util.concurrent.Executor
import kotlin.math.min
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNotNull
@ -763,6 +770,69 @@ class NsdManagerTest {
}
}
private fun checkConnectSocketToMdnsd(shouldFail: Boolean) {
val discoveryRecord = NsdDiscoveryRecord()
val localSocket = LocalSocket()
tryTest {
// Discover any service from NsdManager to enforce NsdService to start the mdnsd.
nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, discoveryRecord)
discoveryRecord.expectCallback<DiscoveryStarted>()
// Checks the /dev/socket/mdnsd is created.
val socket = File("/dev/socket/mdnsd")
val doesSocketExist = PollingCheck.waitFor(
TIMEOUT_MS,
{
socket.exists()
},
{ doesSocketExist ->
doesSocketExist
},
)
// If the socket is not created, then no need to check the access.
if (doesSocketExist) {
// Create a LocalSocket and try to connect to mdnsd.
assertFalse("LocalSocket is connected.", localSocket.isConnected)
val address = LocalSocketAddress("mdnsd", LocalSocketAddress.Namespace.RESERVED)
if (shouldFail) {
assertFailsWith<IOException>("Expect fail but socket connected") {
localSocket.connect(address)
}
} else {
localSocket.connect(address)
assertTrue("LocalSocket is not connected.", localSocket.isConnected)
}
}
} cleanup {
localSocket.close()
nsdManager.stopServiceDiscovery(discoveryRecord)
discoveryRecord.expectCallback<DiscoveryStopped>()
}
}
/**
* Starting from Android U, the access to the /dev/socket/mdnsd is blocked by the
* sepolicy(b/265364111).
*/
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
@Test
fun testCannotConnectSocketToMdnsd() {
val targetSdkVersion = context.packageManager
.getTargetSdkVersion(context.applicationInfo.packageName)
assumeTrue(targetSdkVersion > Build.VERSION_CODES.TIRAMISU)
val firstApiLevel = min(PropertyUtil.getFirstApiLevel(), PropertyUtil.getVendorApiLevel())
// The sepolicy is implemented in the vendor image, so the access may not be blocked if
// the vendor image is not update to date.
assumeTrue(firstApiLevel > Build.VERSION_CODES.TIRAMISU)
checkConnectSocketToMdnsd(shouldFail = true)
}
@Test @CtsNetTestCasesMaxTargetSdk33("mdnsd socket is accessible up to target SDK 33")
fun testCanConnectSocketToMdnsd() {
checkConnectSocketToMdnsd(shouldFail = false)
}
@Test @CtsNetTestCasesMaxTargetSdk30("Socket is started with the service up to target SDK 30")
fun testManagerCreatesLegacySocket() {
nsdManager // Ensure the lazy-init member is initialized, so NsdManager is created