Use BPF to block socket creation when restricted
Adapt BPF's inet socket creation rule to not only check INTERNET permission but also to ensure the uid is on the allowlist for restricted networking (has RESTRICTED_MATCH flag). Also includes squashed change: Author: Tommy Webb <tommy@calyxinstitute.org> Date: Thu Sep 7 03:59:21 2023 -0400 Deny socket creation for transport-blocked apps Prevent apps whose network access is blocked based on transport policies from creating sockets, too. Update the logic to match AOSP's "funky bit-wise arithmetic" from the latest Connectivity mainline. Test: Manual: Turn on Private DNS. Install Terminal Emulator. Connect to Wi-Fi (no VPN). Set Terminal Emulator's toggles to disable Wi-Fi. Run: `ping duckduckgo.com`. Should receive "unknown host" error, NOT "Network is unreachable". Same "unknown host" error should occur when testing with overall network access turned off for Terminal Emulator, with and without its Wi-Fi access also turned off. Issue: calyxos#581 Change-Id: I995e9929f6f8c1ae0613e05e0cade55a76c35902 Co-authored-by: Oliver Scott <olivercscott@gmail.com> Change-Id: I912a4a2ee78a29ca8b7d8ff85e5ad7cf617c31a5 Signed-off-by: Mohammad Hasan Keramat J <ikeramat@protonmail.com>
This commit is contained in:
parent
83fae94950
commit
c013c8dd79
|
@ -343,6 +343,25 @@ static __always_inline inline BpfConfig getConfig(uint32_t configKey) {
|
|||
return *config;
|
||||
}
|
||||
|
||||
#define FIREWALL_DROP_IF_SET (OEM_DENY_1_MATCH)
|
||||
#define FIREWALL_DROP_IF_UNSET (RESTRICTED_MATCH)
|
||||
|
||||
// Must be __always_inline or the call from inet_socket_create will crash-reboot the system
|
||||
static __always_inline inline int bpf_owner_firewall_match(uint32_t uid) {
|
||||
if (is_system_uid(uid)) return PASS;
|
||||
|
||||
const BpfConfig enabledRules = getConfig(UID_RULES_CONFIGURATION_KEY);
|
||||
const UidOwnerValue* uidEntry = bpf_uid_owner_map_lookup_elem(&uid);
|
||||
const uint32_t uidRules = uidEntry ? uidEntry->rule : 0;
|
||||
|
||||
if (enabledRules & (FIREWALL_DROP_IF_SET | FIREWALL_DROP_IF_UNSET)
|
||||
& (uidRules ^ FIREWALL_DROP_IF_UNSET)) {
|
||||
return DROP;
|
||||
}
|
||||
|
||||
return PASS;
|
||||
}
|
||||
|
||||
// DROP_IF_SET is set of rules that DROP if rule is globally enabled, and per-uid bit is set
|
||||
#define DROP_IF_SET (STANDBY_MATCH | OEM_DENY_1_MATCH | OEM_DENY_2_MATCH | OEM_DENY_3_MATCH)
|
||||
// DROP_IF_UNSET is set of rules that should DROP if globally enabled, and per-uid bit is NOT set
|
||||
|
@ -570,22 +589,21 @@ DEFINE_XTBPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_den
|
|||
DEFINE_NETD_BPF_PROG_KVER("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create,
|
||||
KVER(4, 14, 0))
|
||||
(struct bpf_sock* sk) {
|
||||
uint64_t gid_uid = bpf_get_current_uid_gid();
|
||||
uint32_t uid = (bpf_get_current_uid_gid() & 0xffffffff);
|
||||
/*
|
||||
* A given app is guaranteed to have the same app ID in all the profiles in
|
||||
* which it is installed, and install permission is granted to app for all
|
||||
* user at install time so we only check the appId part of a request uid at
|
||||
* run time. See UserHandle#isSameApp for detail.
|
||||
*/
|
||||
uint32_t appId = (gid_uid & 0xffffffff) % AID_USER_OFFSET; // == PER_USER_RANGE == 100000
|
||||
uint32_t appId = uid % AID_USER_OFFSET; // == PER_USER_RANGE == 100000
|
||||
uint8_t* permissions = bpf_uid_permission_map_lookup_elem(&appId);
|
||||
if (!permissions) {
|
||||
// UID not in map. Default to just INTERNET permission.
|
||||
return 1;
|
||||
// If UID is in map but missing BPF_PERMISSION_INTERNET, app has no INTERNET permission.
|
||||
if (permissions && ((*permissions & BPF_PERMISSION_INTERNET) != BPF_PERMISSION_INTERNET)) {
|
||||
return DROP;
|
||||
}
|
||||
|
||||
// A return value of 1 means allow, everything else means deny.
|
||||
return (*permissions & BPF_PERMISSION_INTERNET) == BPF_PERMISSION_INTERNET;
|
||||
// Only allow if uid is not blocked by the user firewall.
|
||||
return bpf_owner_firewall_match(uid);
|
||||
}
|
||||
|
||||
LICENSE("Apache 2.0");
|
||||
|
|
Loading…
Reference in New Issue