Do not block system uid from creating inet socket
Some system uid such as root is not in the package list send to netd
when device start. But they should still have INTERNET permission. Add a
check in eBPF program to stop blocking them from creating sockets. Also
fix the name of program so it can be correctly identified. Also switch
the eBPF map from a whitelist to a blacklist, now only uids in the map
but not have PERMISSION_INTERNET bit set will get blocked. Otherwise the
eBPF map will not block the uid from creating inet/inet6 sockets.
Bug: 111560570
Bug: 128944261
Test: netd_integration_test
Change-Id: I0dd4e74a0f2b301ceea90829eda1564a4922e27a
diff --git a/server/TrafficController.cpp b/server/TrafficController.cpp
index b80de35..9e6247b 100644
--- a/server/TrafficController.cpp
+++ b/server/TrafficController.cpp
@@ -73,6 +73,11 @@
constexpr int kSockDiagMsgType = SOCK_DIAG_BY_FAMILY;
constexpr int kSockDiagDoneMsgType = NLMSG_DONE;
+static_assert(BPF_PERMISSION_INTERNET == INetd::PERMISSION_INTERNET,
+ "Mismatch between BPF and AIDL permissions: PERMISSION_INTERNET");
+static_assert(BPF_PERMISSION_UPDATE_DEVICE_STATS == INetd::PERMISSION_UPDATE_DEVICE_STATS,
+ "Mismatch between BPF and AIDL permissions: PERMISSION_UPDATE_DEVICE_STATS");
+
#define FLAG_MSG_TRANS(result, flag, value) \
do { \
if (value & flag) { \
@@ -103,9 +108,12 @@
}
const std::string UidPermissionTypeToString(uint8_t permission) {
+ if (permission == INetd::NO_PERMISSIONS) {
+ return "NO_PERMISSIONS";
+ }
std::string permissionType;
- FLAG_MSG_TRANS(permissionType, ALLOW_SOCK_CREATE, permission);
- FLAG_MSG_TRANS(permissionType, ALLOW_UPDATE_DEVICE_STATS, permission);
+ FLAG_MSG_TRANS(permissionType, BPF_PERMISSION_INTERNET, permission);
+ FLAG_MSG_TRANS(permissionType, BPF_PERMISSION_UPDATE_DEVICE_STATS, permission);
if (permission) {
return StringPrintf("Unknown permission: %u", permission);
}
@@ -676,20 +684,30 @@
}
void TrafficController::setPermissionForUids(int permission, const std::vector<uid_t>& uids) {
+ if (permission == INetd::PERMISSION_UNINSTALLED) {
+ for (uid_t uid : uids) {
+ // Clean up all permission information for the related uid if all the
+ // packages related to it are uninstalled.
+ mPrivilegedUser.erase(uid);
+ Status ret = mUidPermissionMap.deleteValue(uid);
+ }
+ return;
+ }
+
bool internet = (permission & INetd::PERMISSION_INTERNET);
bool privileged = (permission & INetd::PERMISSION_UPDATE_DEVICE_STATS);
for (uid_t uid : uids) {
- if (internet) {
- Status ret = mUidPermissionMap.writeValue(uid, ALLOW_SOCK_CREATE, BPF_ANY);
+ if (!internet) {
+ Status ret = mUidPermissionMap.writeValue(uid, permission, BPF_ANY);
if (!isOk(ret)) {
- ALOGE("Failed to grant INTERNET permission to uid: %u: %s", uid,
+ ALOGE("Failed to block INTERNET permission to uid: %u: %s", uid,
strerror(ret.code()));
}
} else {
Status ret = mUidPermissionMap.deleteValue(uid);
if (!isOk(ret) && ret.code() != ENOENT) {
- ALOGE("Failed to revoke permission INTERNET from uid: %u: %s", uid,
+ ALOGE("Failed to unlock INTERNET permission for uid: %u: %s", uid,
strerror(ret.code()));
}
}