Use bpf maps to store permission information

In newer kernels, we can use cgroup socket filter to control inet socket
creation at run time instead of paranoid network kernel check. To
achieve that, we need to get the permission information from system
server when device boots or new packages are installed. This patch
provides a binder interface to do that and stores the information in a
bpf map. It also records the uids that have permission
UPDATE_DEVICE_STATS so netd no longer needs to query that from the
system server.

Bug: 111560570
Bug: 111560739
Test: netd_unit_test, netd_integration_test

Change-Id: I0c5919d85136feec44c4406ee0bd0028b131b942
diff --git a/server/TrafficController.h b/server/TrafficController.h
index c66bc36..263377f 100644
--- a/server/TrafficController.h
+++ b/server/TrafficController.h
@@ -116,6 +116,8 @@
 
     static netdutils::StatusOr<std::unique_ptr<NetlinkListenerInterface>> makeSkDestroyListener();
 
+    void setPermissionForUids(int permission, const std::vector<uid_t>& uids);
+
   private:
     /*
      * mCookieTagMap: Store the corresponding tag and uid for a specific socket.
@@ -189,6 +191,11 @@
      */
     BpfMap<uint32_t, uint8_t> mUidOwnerMap GUARDED_BY(mOwnerMatchMutex);
 
+    /*
+     * mUidOwnerMap: Store uids that are used for INTERNET permission check.
+     */
+    BpfMap<uint32_t, uint8_t> mUidPermissionMap;
+
     std::unique_ptr<NetlinkListenerInterface> mSkDestroyListener;
 
     netdutils::Status removeMatch(BpfMap<uint32_t, uint8_t>& map, uint32_t uid,
@@ -206,6 +213,10 @@
 
     netdutils::Status initMaps();
 
+    // Keep track of uids that have permission UPDATE_DEVICE_STATS so we don't
+    // need to call back to system server for permission check.
+    std::set<uid_t> mPrivilegedUser;
+
     UidOwnerMatchType jumpOpToMatch(BandwidthController::IptJumpOp jumpHandling);
     // For testing
     friend class TrafficControllerTest;