Merge "bpf: Filter localhost packages if sent/received by sdksandbox process" into main

This commit is contained in:
Treehugger Robot 2025-04-08 16:24:13 -07:00 • committed by Android (Google) Code Review
commit db4e099b31
2 changed files with 32 additions and 13 deletions

View file

@ -433,6 +433,20 @@ static __always_inline inline BpfConfig getConfig(uint32_t configKey) {
return *config;
}
static __always_inline inline uint8_t get_uid_permissions(uint32_t uid) {
/*
* 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 an app for all
* users 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 = uid % AID_USER_OFFSET; // == PER_USER_RANGE == 100000
uint8_t *permissions = bpf_uid_permission_map_lookup_elem(&appId);
// if UID not in map, then default to just INTERNET permission.
return permissions ? *permissions : BPF_PERMISSION_INTERNET;
}
static __always_inline inline bool ingress_should_discard(struct __sk_buff* skb,
const struct kver_uint kver) {
// Require 4.19, since earlier kernels don't have bpf_skb_load_bytes_relative() which
@ -496,8 +510,9 @@ static __always_inline inline int bpf_owner_match(struct __sk_buff* skb, uint32_
}
}
if (SDK_LEVEL_IS_AT_LEAST(lvl, 25Q2) && skb->ifindex == 1) {
// TODO: sdksandbox localhost restrictions
if (SDK_LEVEL_IS_AT_LEAST(lvl, 25Q2) && skb->ifindex == 1 && is_sdksandbox_uid(uid)) {
// check if the UID is allowed localhost connections
if (!(get_uid_permissions(uid) & BPF_PERMISSION_SDKSANDBOX_LOCALHOST)) return DROP;
}
return PASS;
@ -759,17 +774,7 @@ DEFINE_XTBPF_PROG("skfilter/denylist/xtbpf", xt_bpf_denylist_prog)
}
static __always_inline inline uint8_t get_app_permissions() {
uint64_t gid_uid = bpf_get_current_uid_gid();
/*
* 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
uint8_t* permissions = bpf_uid_permission_map_lookup_elem(&appId);
// if UID not in map, then default to just INTERNET permission.
return permissions ? *permissions : BPF_PERMISSION_INTERNET;
return get_uid_permissions(bpf_get_current_uid_gid() & 0xffffffff);
}
static __always_inline inline int inet_socket_create(struct bpf_sock* sk,

View file

@ -215,10 +215,16 @@ enum UidOwnerMatchType : uint32_t {
};
// LINT.ThenChange(../framework/src/android/net/BpfNetMapsConstants.java)
// LINT.IfChange(bpf_permission)
// The BpfPermissionMatch values should match the traffic permissions defined in NetworkPermissions:
// BPF_PERMISSION_<X> should have the same value that TRAFFIC_PERMISSION_<X>
enum BpfPermissionMatch : uint8_t {
BPF_PERMISSION_INTERNET = 1 << 2,
BPF_PERMISSION_UPDATE_DEVICE_STATS = 1 << 3,
BPF_PERMISSION_SDKSANDBOX_LOCALHOST = 1 << 4,
};
// LINT.ThenChange(packages/modules/Connectivity/service/src/com/android/server/connectivity/NetworkPermissions.java)
// In production we use two identical stats maps to record per uid stats and
// do swap and clean based on the configuration specified here. The statsMapType
// value in configuration map specified which map is currently in use.
@ -293,3 +299,11 @@ static inline bool is_system_uid(uint32_t uid) {
// MAX_SYSTEM_UID is AID_NOBODY == 9999, while AID_APP_START == 10000
return ((uid % AID_USER_OFFSET) < AID_APP_START);
}
static inline bool is_sdksandbox_uid(uint32_t uid) {
uint32_t appid = uid % AID_USER_OFFSET;
// AID_SDK_SANDBOX_PROCESS_START = 20000
// AID_SDK_SANDBOX_PROCESS_END = 29999
return appid >= AID_SDK_SANDBOX_PROCESS_START &&
appid <= AID_SDK_SANDBOX_PROCESS_END;
}