Merge "Fix spurious mutex lock in MDnsEventReporter"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 5e200e9..4e5a047 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -3,6 +3,7 @@
         { "name": "netd_integration_test" },
         { "name": "netd_unit_test" },
         { "name": "netdclient_test" },
+        { "name": "netdclient_root_test" },
         { "name": "netdutils_test" }
     ],
     "postsubmit": [
@@ -18,6 +19,7 @@
         { "name": "netd_integration_test" },
         { "name": "netd_unit_test" },
         { "name": "netdclient_test" },
+        { "name": "netdclient_root_test" },
         { "name": "netdutils_test" }
     ]
 }
diff --git a/client/Android.bp b/client/Android.bp
index 22cb5c1..528b354 100644
--- a/client/Android.bp
+++ b/client/Android.bp
@@ -65,3 +65,28 @@
         recover: [ "all" ],
     },
 }
+
+cc_test {
+    name: "netdclient_root_test",
+    require_root: true,  // for ScopedUidChange
+    srcs: [
+        "NetdClientRootTest.cpp",
+    ],
+    defaults: [
+        "netd_aidl_interface_lateststable_cpp_static",
+        "netd_defaults",
+    ],
+    test_suites: ["device-tests"],
+    include_dirs: [
+        "system/netd/include",
+    ],
+    static_libs: [
+        "libbase",
+        "libnetd_client",
+        "libnetd_test_utils",
+    ],
+    sanitize: {
+        address: false,
+        recover: [ "all" ],
+    },
+}
diff --git a/client/NetdClientRootTest.cpp b/client/NetdClientRootTest.cpp
new file mode 100644
index 0000000..3ecbcef
--- /dev/null
+++ b/client/NetdClientRootTest.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/unique_fd.h>
+#include <gtest/gtest.h>
+
+#include "NetdClient.h"
+#include "android/net/INetd.h"
+#include "netid_client.h"
+#include "test_utils.h"
+
+constexpr int TEST_UID1 = 99999;
+
+TEST(NetdClientTest, setSocketToInvalidNetwork) {
+    const android::base::unique_fd s(socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0));
+    ASSERT_LE(0, s);
+
+    unsigned netId = NETID_UNSET;
+    const ScopedUidChange scopedUidChange(TEST_UID1);
+    EXPECT_EQ(-EACCES, setNetworkForSocket(android::net::INetd::LOCAL_NET_ID, s));
+    EXPECT_EQ(0, getNetworkForSocket(&netId, s));
+    EXPECT_EQ(static_cast<unsigned>(NETID_UNSET), netId);
+}
diff --git a/server/DummyNetwork.h b/server/DummyNetwork.h
index 8f9960b..e699dad 100644
--- a/server/DummyNetwork.h
+++ b/server/DummyNetwork.h
@@ -25,6 +25,7 @@
     static const char* INTERFACE_NAME;
     explicit DummyNetwork(unsigned netId);
     virtual ~DummyNetwork();
+    Permission getPermission() const { return PERMISSION_SYSTEM; };
 
   private:
     std::string getTypeString() const override { return "DUMMY"; };
diff --git a/server/LocalNetwork.h b/server/LocalNetwork.h
index c774067..af56d24 100644
--- a/server/LocalNetwork.h
+++ b/server/LocalNetwork.h
@@ -24,6 +24,7 @@
 public:
     explicit LocalNetwork(unsigned netId);
     virtual ~LocalNetwork();
+    Permission getPermission() const { return PERMISSION_SYSTEM; };
 
 private:
     std::string getTypeString() const override { return "LOCAL"; };
diff --git a/server/Network.h b/server/Network.h
index dfead17..6c3d01d 100644
--- a/server/Network.h
+++ b/server/Network.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include "NetdConstants.h"
+#include "Permission.h"
 #include "UidRanges.h"
 
 #include <set>
@@ -48,6 +49,7 @@
     std::string toString() const;
     std::string uidRangesToString() const;
     bool appliesToUser(uid_t uid, int32_t* subPriority) const;
+    virtual Permission getPermission() const = 0;
     [[nodiscard]] virtual int addUsers(const UidRanges&, int32_t /*subPriority*/) {
         return -EINVAL;
     };
diff --git a/server/NetworkController.cpp b/server/NetworkController.cpp
index f144139..ca9ec22 100644
--- a/server/NetworkController.cpp
+++ b/server/NetworkController.cpp
@@ -887,7 +887,7 @@
     // Check whether the UID's permission bits are sufficient to use the network.
     // Because the permission of the system default network is PERMISSION_NONE(0x0), apps can always
     // pass the check here when using the system default network.
-    Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission();
+    const Permission networkPermission = network->getPermission();
     return ((userPermission & networkPermission) == networkPermission) ? 0 : -EACCES;
 }
 
diff --git a/server/RouteController.h b/server/RouteController.h
index 1b3a093..0d4e2b9 100644
--- a/server/RouteController.h
+++ b/server/RouteController.h
@@ -85,13 +85,6 @@
 constexpr int32_t RULE_PRIORITY_UNREACHABLE                       = 32000;
 // clang-format on
 
-static const char* V4_FIXED_LOCAL_PREFIXES[] = {
-        // The multicast range is 224.0.0.0/4 but only limit it to 224.0.0.0/24 since the IPv4
-        // definitions are not as precise as for IPv6, it is the only range that the standards
-        // (RFC 2365 and RFC 5771) specify is link-local and must not be forwarded.
-        "224.0.0.0/24"  // Link-local multicast; non-internet routable
-};
-
 class UidRanges;
 
 class RouteController {
@@ -205,6 +198,14 @@
   private:
     friend class RouteControllerTest;
 
+    // An expandable array for fixed local prefix though it's only one element now.
+    static constexpr const char* V4_FIXED_LOCAL_PREFIXES[] = {
+            // The multicast range is 224.0.0.0/4 but only limit it to 224.0.0.0/24 since the IPv4
+            // definitions are not as precise as for IPv6, it is the only range that the standards
+            // (RFC 2365 and RFC 5771) specify is link-local and must not be forwarded.
+            "224.0.0.0/24"  // Link-local multicast; non-internet routable
+    };
+
     static std::mutex sInterfaceToTableLock;
     static std::map<std::string, uint32_t> sInterfaceToTable GUARDED_BY(sInterfaceToTableLock);
 
diff --git a/server/UnreachableNetwork.h b/server/UnreachableNetwork.h
index d2cefde..0ffc0ce 100644
--- a/server/UnreachableNetwork.h
+++ b/server/UnreachableNetwork.h
@@ -23,6 +23,7 @@
 class UnreachableNetwork : public Network {
   public:
     explicit UnreachableNetwork(unsigned netId);
+    Permission getPermission() const { return PERMISSION_SYSTEM; };
     [[nodiscard]] int addUsers(const UidRanges& uidRanges, int32_t subPriority) override;
     [[nodiscard]] int removeUsers(const UidRanges& uidRanges, int32_t subPriority) override;
     bool isUnreachable() override { return true; }
diff --git a/server/VirtualNetwork.h b/server/VirtualNetwork.h
index 63bc589..6e9bdad 100644
--- a/server/VirtualNetwork.h
+++ b/server/VirtualNetwork.h
@@ -35,6 +35,7 @@
 public:
   explicit VirtualNetwork(unsigned netId, bool secure, bool excludeLocalRoutes = false);
   virtual ~VirtualNetwork();
+  Permission getPermission() const { return PERMISSION_SYSTEM; };
   [[nodiscard]] int addUsers(const UidRanges& uidRanges, int32_t subPriority) override;
   [[nodiscard]] int removeUsers(const UidRanges& uidRanges, int32_t subPriority) override;
   bool isVirtual() override { return true; }
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index 2ca21ff..0709204 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -138,7 +138,6 @@
 using android::net::TunInterface;
 using android::net::UidRangeParcel;
 using android::net::UidRanges;
-using android::net::V4_FIXED_LOCAL_PREFIXES;
 using android::net::mdns::aidl::DiscoveryInfo;
 using android::net::mdns::aidl::GetAddressInfo;
 using android::net::mdns::aidl::IMDns;
@@ -1689,6 +1688,10 @@
             {IP_RULE_V6, "2001:db8::/32", ""},
     };
 
+    // This should ba aligned with V4_FIXED_LOCAL_PREFIXES in system/netd/server/RouteController.cpp
+    // An expandable array for fixed local prefix though it's only one element now.
+    static const char* kV4LocalPrefixes[] = {"224.0.0.0/24"};
+
     // Add test physical network
     const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
                                                  INetd::PERMISSION_NONE, false, false);
@@ -1705,8 +1708,8 @@
     std::string localTableName = std::string(sTun.name() + "_local");
 
     // Verify the fixed routes exist in the local table.
-    for (size_t i = 0; i < std::size(V4_FIXED_LOCAL_PREFIXES); i++) {
-        expectNetworkRouteExists(IP_RULE_V4, sTun.name(), V4_FIXED_LOCAL_PREFIXES[i], "",
+    for (size_t i = 0; i < std::size(kV4LocalPrefixes); i++) {
+        expectNetworkRouteExists(IP_RULE_V4, sTun.name(), kV4LocalPrefixes[i], "",
                                  localTableName.c_str());
     }