Don't call into system_server for permissions check

With the recently added permission information in traffic controller,
netd can check if the calling process has permission UPDATE_DEVICE_STATS
without calling into system_server. Update the code path and add some
test cases for it.

Bug: 111560570
Bug: 111560739
Test: netd_unit_test, netd_integration_test
Change-Id: I79eee1321f32154e91466f023f7952db23df8494
diff --git a/server/TrafficController.cpp b/server/TrafficController.cpp
index 9aaa9fa..a30f9dd 100644
--- a/server/TrafficController.cpp
+++ b/server/TrafficController.cpp
@@ -92,6 +92,10 @@
     return matchType;
 }
 
+bool TrafficController::hasUpdateDeviceStatsPermission(uid_t uid) {
+    return mPrivilegedUser.find(uid) != mPrivilegedUser.end();
+}
+
 const std::string UidPermissionTypeToString(uint8_t permission) {
     std::string permissionType;
     FLAG_MSG_TRANS(permissionType, ALLOW_SOCK_CREATE, permission);
@@ -299,7 +303,11 @@
     return netdutils::status::ok;
 }
 
-int TrafficController::tagSocket(int sockFd, uint32_t tag, uid_t uid) {
+int TrafficController::tagSocket(int sockFd, uint32_t tag, uid_t uid, uid_t callingUid) {
+    if (uid != callingUid && !hasUpdateDeviceStatsPermission(callingUid)) {
+        return -EPERM;
+    }
+
     if (!ebpfSupported) {
         if (legacy_tagSocket(sockFd, tag, uid)) return -errno;
         return 0;
@@ -337,9 +345,11 @@
     return -res.code();
 }
 
-int TrafficController::setCounterSet(int counterSetNum, uid_t uid) {
+int TrafficController::setCounterSet(int counterSetNum, uid_t uid, uid_t callingUid) {
     if (counterSetNum < 0 || counterSetNum >= OVERFLOW_COUNTERSET) return -EINVAL;
-    Status res;
+
+    if (!hasUpdateDeviceStatsPermission(callingUid)) return -EPERM;
+
     if (!ebpfSupported) {
         if (legacy_setCounterSet(counterSetNum, uid)) return -errno;
         return 0;
@@ -357,7 +367,7 @@
         }
     }
     uint8_t tmpCounterSetNum = (uint8_t)counterSetNum;
-    res = mUidCounterSetMap.writeValue(uid, tmpCounterSetNum, BPF_ANY);
+    Status res = mUidCounterSetMap.writeValue(uid, tmpCounterSetNum, BPF_ANY);
     if (!isOk(res)) {
         ALOGE("Failed to set the counterSet: %s, fd: %d", strerror(res.code()),
               mUidCounterSetMap.getMap().get());
@@ -369,7 +379,9 @@
 // This method only get called by system_server when an app get uinstalled, it
 // is called inside removeUidsLocked() while holding mStatsLock. So it is safe
 // to iterate and modify the stats maps.
-int TrafficController::deleteTagData(uint32_t tag, uid_t uid) {
+int TrafficController::deleteTagData(uint32_t tag, uid_t uid, uid_t callingUid) {
+    if (!hasUpdateDeviceStatsPermission(callingUid)) return -EPERM;
+
     if (!ebpfSupported) {
         if (legacy_deleteTagData(tag, uid)) return -errno;
         return 0;