• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved.
3 
4 * The netsys.c is dual licensed: you can use it either under the terms of
5 * the GPL V2, or the 3-Clause BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8 
9 #include <linux/bpf.h>
10 #include <linux/if_packet.h>
11 #include <linux/if.h>
12 #include <linux/if_ether.h>
13 #include <linux/string.h>
14 #include <string.h>
15 #include <stddef.h>
16 #include <stdint.h>
17 
18 #include "bpf/bpf_helpers.h"
19 #include "bpf_def.h"
20 
21 #ifdef FEATURE_NET_FIREWALL_ENABLE
22 #include "netfirewall/netfirewall.h"
23 #endif //FEATURE_NET_FIREWALL_ENABLE
24 
25 #define SEC(NAME) __attribute__((section(NAME), used))
26 
27 #ifdef SUPPORT_EBPF_MEM_MIN
28 static const int32_t APP_STATS_MAP_SIZE = 200;
29 static const int32_t APP_STATS_MAP_SIZE_MIN = 1;
30 static const int32_t IFACE_STATS_MAP_SIZE = 64;
31 static const int32_t IFACE_NAME_MAP_SIZE = 200;
32 static const int32_t IFACE_NAME_MAP_SIZE_MIN = 1;
33 static const int32_t OH_SOCK_PERMISSION_MAP_SIZE = 200;
34 static const int32_t BROKER_SOCK_PERMISSION_MAP_SIZE = 1;
35 static const int32_t UID_ACCESS_POLICY_ARRAY_SIZE = 1000;
36 static const int32_t NET_NS_MAP_SIZE = 2000;
37 #else
38 static const int32_t APP_STATS_MAP_SIZE = 5000;
39 static const int32_t APP_STATS_MAP_SIZE_MIN = 5000;
40 static const int32_t IFACE_STATS_MAP_SIZE = 1000;
41 static const int32_t IFACE_NAME_MAP_SIZE = 1000;
42 static const int32_t IFACE_NAME_MAP_SIZE_MIN = 1000;
43 static const int32_t OH_SOCK_PERMISSION_MAP_SIZE = 1000;
44 static const int32_t BROKER_SOCK_PERMISSION_MAP_SIZE = 1000;
45 static const int32_t UID_ACCESS_POLICY_ARRAY_SIZE = 65535;
46 static const int32_t NET_NS_MAP_SIZE = 5000;
47 #endif
48 
49 // network stats begin
50 bpf_map_def SEC("maps") iface_stats_map = {
51     .type = BPF_MAP_TYPE_HASH,
52     .key_size = sizeof(uint64_t),
53     .value_size = sizeof(iface_stats_value),
54     .max_entries = IFACE_STATS_MAP_SIZE,
55     .map_flags = 0,
56     .inner_map_idx = 0,
57     .numa_node = 0,
58 };
59 
60 bpf_map_def SEC("maps") app_uid_stats_map = {
61     .type = BPF_MAP_TYPE_HASH,
62     .key_size = sizeof(uint64_t),
63     .value_size = sizeof(app_uid_stats_value),
64     .max_entries = APP_STATS_MAP_SIZE,
65     .map_flags = 0,
66     .inner_map_idx = 0,
67     .numa_node = 0,
68 };
69 
70 bpf_map_def SEC("maps") sock_netns_map = {
71     .type = BPF_MAP_TYPE_HASH,
72     .key_size = sizeof(sock_netns_key),
73     .value_size = sizeof(sock_netns_value),
74     .max_entries = NET_NS_MAP_SIZE,
75     .map_flags = 0,
76     .inner_map_idx = 0,
77     .numa_node = 0,
78 };
79 
80 bpf_map_def SEC("maps") app_uid_sim_stats_map = {
81     .type = BPF_MAP_TYPE_HASH,
82     .key_size = sizeof(app_uid_sim_stats_key),
83     .value_size = sizeof(app_uid_sim_stats_value),
84     .max_entries = APP_STATS_MAP_SIZE,
85     .map_flags = 0,
86     .inner_map_idx = 0,
87     .numa_node = 0,
88 };
89 
90 bpf_map_def SEC("maps") app_uid_if_stats_map = {
91     .type = BPF_MAP_TYPE_HASH,
92     .key_size = sizeof(app_uid_if_stats_key),
93     .value_size = sizeof(app_uid_if_stats_value),
94     .max_entries = IFACE_NAME_MAP_SIZE,
95     .map_flags = 0,
96     .inner_map_idx = 0,
97     .numa_node = 0,
98 };
99 
100 bpf_map_def SEC("maps") app_cookie_stats_map = {
101     .type = BPF_MAP_TYPE_HASH,
102     .key_size = sizeof(socket_cookie_stats_key),
103     .value_size = sizeof(app_cookie_stats_value),
104     .max_entries = IFACE_NAME_MAP_SIZE_MIN,
105     .map_flags = 0,
106     .inner_map_idx = 0,
107     .numa_node = 0,
108 };
109 
110 // 1. 建立一个可用限额map
111 bpf_map_def SEC("maps") limits_stats_map = {
112     .type = BPF_MAP_TYPE_HASH,
113     .key_size = sizeof(traffic_notify_flag),
114     .value_size = sizeof(traffic_value),
115     .max_entries = 3, // 3:   0-monthly limit 1-monthly mark 2-daily mark
116     .map_flags = 0,
117     .inner_map_idx = 0,
118     .numa_node = 0,
119 };
120 
121 // 2. 建立一个增量map
122 bpf_map_def SEC("maps") increment_stats_map = {
123     .type = BPF_MAP_TYPE_HASH,
124     .key_size = sizeof(uint64_t),
125     .value_size = sizeof(traffic_value),
126     .max_entries = 1, // current only support single card detect
127     .map_flags = 0,
128     .inner_map_idx = 0,
129     .numa_node = 0,
130 };
131 
132 // 3. 网卡index
133 bpf_map_def SEC("maps") ifindex_map = {
134     .type = BPF_MAP_TYPE_HASH,
135     .key_size = sizeof(uint8_t),
136     .value_size = sizeof(uint64_t),
137     .max_entries = 20,
138     .map_flags = 0,
139     .inner_map_idx = 0,
140     .numa_node = 0,
141 };
142 
143 bpf_map_def SEC("maps") net_stats_ringbuf_map = {
144     .type = BPF_MAP_TYPE_RINGBUF,
145     .max_entries = 256 * 1024 /* 256 KB */,
146 };
147 
socket_ringbuf_net_stats_event_submit(__u8 flag)148 static inline __u8 socket_ringbuf_net_stats_event_submit(__u8 flag)
149 {
150     uint8_t *e;
151     e = bpf_ringbuf_reserve(&net_stats_ringbuf_map, sizeof(uint8_t), 0);
152     if (e) {
153         *e = flag;
154         bpf_ringbuf_submit(e, 0);
155         return 1;
156     }
157     return 0;
158 }
159 
get_data_len(struct __sk_buff * skb)160 static inline __u32 get_data_len(struct __sk_buff *skb)
161 {
162     __u32 length = skb->len;
163     if (skb->vlan_present == 1) {
164         length += VLAN_HEADER_LENGTH;
165     }
166     if (skb->family == AF_INET) {
167         length += IPV4_HEADERS_LENGTH;
168     }
169     if (skb->family == AF_INET6) {
170         length += IPV6_HEADERS_LENGTH;
171     }
172     return length;
173 }
174 
update_new_incre_value(uint64_t ifindex,__u32 len)175 static traffic_value update_new_incre_value(uint64_t ifindex, __u32 len)
176 {
177     traffic_value *old_value = bpf_map_lookup_elem(&increment_stats_map, &ifindex);
178     if (old_value == NULL) {
179         traffic_value newValue = 0;
180         bpf_map_update_elem(&increment_stats_map, &ifindex, &newValue, BPF_NOEXIST);
181         old_value = bpf_map_lookup_elem(&increment_stats_map, &ifindex);
182     }
183 
184     if (old_value != NULL) {
185         *old_value = (*old_value) + len;
186         bpf_map_update_elem(&increment_stats_map, &ifindex, old_value, BPF_ANY);
187         return *old_value;
188     }
189     return 0;
190 }
191 
is_exceed_daily_mark(traffic_value used_value)192 static traffic_notify_flag is_exceed_daily_mark(traffic_value used_value)
193 {
194     traffic_notify_flag daily_mark = 2; // 2: DAILY_MARK
195     traffic_value *day_mark_avai = bpf_map_lookup_elem(&limits_stats_map, &daily_mark);
196 
197     traffic_value max_value = UINT64_MAX;
198     if (day_mark_avai == NULL) {
199         bpf_map_update_elem(&limits_stats_map, &daily_mark, &max_value, BPF_NOEXIST);
200         day_mark_avai = bpf_map_lookup_elem(&limits_stats_map, &daily_mark);
201     }
202     if (day_mark_avai != NULL && used_value > *day_mark_avai) {
203         bpf_map_update_elem(&limits_stats_map, &daily_mark, &max_value, BPF_ANY);
204         return daily_mark;
205     }
206     return UINT8_MAX;
207 }
208 
is_exceed_mothly_mark(traffic_value used_value)209 static traffic_notify_flag is_exceed_mothly_mark(traffic_value used_value)
210 {
211     traffic_notify_flag monthly_mark = 1; // 1: MONTHLY_MARK
212     traffic_value *monthly_mark_avai = bpf_map_lookup_elem(&limits_stats_map, &monthly_mark);
213 
214     traffic_value max_value = UINT64_MAX;
215     if (monthly_mark_avai == NULL) {
216         bpf_map_update_elem(&limits_stats_map, &monthly_mark, &max_value, BPF_NOEXIST);
217         monthly_mark_avai = bpf_map_lookup_elem(&limits_stats_map, &monthly_mark);
218     }
219     if (monthly_mark_avai != NULL && used_value > *monthly_mark_avai) {
220         bpf_map_update_elem(&limits_stats_map, &monthly_mark, &max_value, BPF_ANY);
221         return monthly_mark;
222     }
223     return UINT8_MAX;
224 }
225 
is_exceed_mothly_limit(traffic_value used_value)226 static traffic_notify_flag is_exceed_mothly_limit(traffic_value used_value)
227 {
228     traffic_notify_flag monthly_limit = 0; // 0: MONTHLY_LIMIT
229     traffic_value *monthly_limit_avai = bpf_map_lookup_elem(&limits_stats_map, &monthly_limit);
230 
231     traffic_value max_value = UINT64_MAX;
232     if (monthly_limit_avai == NULL) {
233         bpf_map_update_elem(&limits_stats_map, &monthly_limit, &max_value, BPF_NOEXIST);
234         monthly_limit_avai = bpf_map_lookup_elem(&limits_stats_map, &monthly_limit);
235     }
236     if (monthly_limit_avai != NULL && used_value > *monthly_limit_avai) {
237         bpf_map_update_elem(&limits_stats_map, &monthly_limit, &max_value, BPF_ANY);
238         return monthly_limit;
239     }
240     return UINT8_MAX;
241 }
242 
243 SEC("socket/iface/stats")
socket_iface_stats(struct __sk_buff * skb)244 int socket_iface_stats(struct __sk_buff *skb)
245 {
246     if (skb == NULL) {
247         return 1;
248     }
249 
250     if (skb->pkt_type == PACKET_LOOPBACK) {
251         return 1;
252     }
253 
254     uint64_t ifindex = skb->ifindex;
255     iface_stats_value *value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
256     if (value_if == NULL) {
257         iface_stats_value newValue = {};
258         bpf_map_update_elem(&iface_stats_map, &ifindex, &newValue, BPF_NOEXIST);
259         value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
260     }
261 
262     if (skb->pkt_type == PACKET_OUTGOING) {
263         if (value_if != NULL) {
264             __sync_fetch_and_add(&value_if->txPackets, 1);
265             __sync_fetch_and_add(&value_if->txBytes, skb->len);
266         }
267     } else {
268         if (value_if != NULL) {
269             __sync_fetch_and_add(&value_if->rxPackets, 1);
270             __sync_fetch_and_add(&value_if->rxBytes, skb->len);
271         }
272     }
273 
274     uint8_t id = 0; // current only support single card detect.
275     uint64_t *cur_rmnet_ifindex = bpf_map_lookup_elem(&ifindex_map, &id);
276     if (cur_rmnet_ifindex == NULL || *cur_rmnet_ifindex != ifindex) {
277         return 1;
278     }
279 
280     traffic_value used_value = update_new_incre_value(ifindex, skb->len);
281     if (used_value == 0) {
282         return 1;
283     }
284     traffic_notify_flag flag = is_exceed_mothly_limit(used_value);
285     if (flag == UINT8_MAX) {
286         flag = is_exceed_mothly_mark(used_value);
287         if (flag == UINT8_MAX) {
288             flag = is_exceed_daily_mark(used_value);
289         }
290     }
291     if (flag != UINT8_MAX) {
292         socket_ringbuf_net_stats_event_submit(flag);
293     }
294 
295     return 1;
296 }
297 
298 bpf_map_def SEC("maps") app_uid_access_policy_map = {
299     .type = BPF_MAP_TYPE_HASH,
300     .key_size = sizeof(app_uid_key),
301     .value_size = sizeof(uid_access_policy_value),
302     .max_entries = UID_ACCESS_POLICY_ARRAY_SIZE,
303     .map_flags = BPF_F_NO_PREALLOC,
304     .inner_map_idx = 0,
305     .numa_node = 0,
306 };
307 
308 bpf_map_def SEC("maps") broker_uid_access_policy_map = {
309     .type = BPF_MAP_TYPE_HASH,
310     .key_size = sizeof(app_uid_key),
311     .value_size = sizeof(app_uid_key),
312     .max_entries = APP_STATS_MAP_SIZE_MIN,
313     .map_flags = BPF_F_NO_PREALLOC,
314     .inner_map_idx = 0,
315     .numa_node = 0,
316 };
317 
318 bpf_map_def SEC("maps") net_index_and_iface_map = {
319     .type = BPF_MAP_TYPE_HASH,
320     .key_size = sizeof(net_index),
321     .value_size = sizeof(net_interface_name_id),
322     .max_entries = 5,
323     .map_flags = 0,
324     .inner_map_idx = 0,
325     .numa_node = 0,
326 };
327 
check_socket_fwmark(__u32 mark)328 static inline net_bear_type_map_value check_socket_fwmark(__u32 mark)
329 {
330     __u8 explicitlySelected = (mark >> 16) & (0x1);
331     net_bear_type_map_value net_bear_mark_type = NETWORK_BEARER_TYPE_INITIAL;
332     // explicitlySelected == 1 means the socket fwmark is set
333     if (explicitlySelected == 1) {
334         void *ifaceC_map_ptr = &net_index_and_iface_map;
335         __u16 TmpnetId = mark & (0x0000FFFF);
336         net_interface_name_id *ifaceC = bpf_map_lookup_elem(ifaceC_map_ptr, &TmpnetId);
337         // ifaceC == NULL, default bear type (*net_bear_type) is used.
338         if (ifaceC != NULL) {
339             net_bear_mark_type = *ifaceC;
340         }
341     }
342     return net_bear_mark_type;
343 }
344 
345 bpf_map_def SEC("maps") net_bear_type_map = {
346     .type = BPF_MAP_TYPE_HASH,
347     .key_size = sizeof(net_bear_id_key),
348     .value_size = sizeof(net_bear_type_map_value),
349     .max_entries = IFACE_NAME_MAP_SIZE,
350     .map_flags = 0,
351     .inner_map_idx = 0,
352     .numa_node = 0,
353 };
354 
check_network_policy(net_bear_type_map_value net_bear_mark_type,uid_access_policy_value * netAccessPolicyValue)355 static inline __u8 check_network_policy(net_bear_type_map_value net_bear_mark_type,
356                                         uid_access_policy_value *netAccessPolicyValue)
357 {
358     if (((net_bear_mark_type == NETWORK_BEARER_TYPE_WIFI) && (!netAccessPolicyValue->wifiPolicy)) ||
359         ((net_bear_mark_type == NETWORK_BEARER_TYPE_CELLULAR) && (!netAccessPolicyValue->cellularPolicy))) {
360         return 0;
361     } else if (net_bear_mark_type != NETWORK_BEARER_TYPE_INITIAL) {
362         return 1;
363     }
364     if (((netAccessPolicyValue->netIfIndex == NETWORK_BEARER_TYPE_WIFI) && (!netAccessPolicyValue->wifiPolicy)) ||
365         ((netAccessPolicyValue->netIfIndex == NETWORK_BEARER_TYPE_CELLULAR) &&
366         (!netAccessPolicyValue->cellularPolicy))) {
367         return 0;
368     }
369     if (netAccessPolicyValue->netIfIndex == NETWORK_BEARER_TYPE_INITIAL) {
370         void *net_bear_map_ptr = &net_bear_type_map;
371         net_bear_id_key net_bear_id = DEFAULT_NETWORK_BEARER_MAP_KEY;
372         net_bear_type_map_value *net_bear_type = bpf_map_lookup_elem(net_bear_map_ptr, &net_bear_id);
373         if (net_bear_type == NULL) {
374             return 1;
375         }
376 
377         if (((*net_bear_type == NETWORK_BEARER_TYPE_CELLULAR)) && (!netAccessPolicyValue->cellularPolicy)) {
378             return 0;
379         }
380         if (((*net_bear_type == NETWORK_BEARER_TYPE_WIFI)) && (!netAccessPolicyValue->wifiPolicy)) {
381             return 0;
382         }
383     }
384     return 1;
385 }
386 
check_broker_policy(uint64_t uid)387 static inline __u64 check_broker_policy(uint64_t uid)
388 {
389     uint64_t network_access_uid = uid;
390     void *broker_map_ptr = &broker_uid_access_policy_map;
391     app_uid_key *broker_uid_key = (app_uid_key *)&uid;
392     app_uid_key *broker_uid_value = bpf_map_lookup_elem(broker_map_ptr, broker_uid_key);
393     if (broker_uid_value != NULL) {
394         network_access_uid = *broker_uid_value;
395         return network_access_uid;
396     } else {
397         __u32 broker_default_uid = DEFAULT_BROKER_UID_KEY;
398         app_uid_key *broker_default_value = bpf_map_lookup_elem(broker_map_ptr, &broker_default_uid);
399         if (broker_default_value != NULL && uid > SIM_UID_MIN && uid < SIM_UID_MAX) {
400             network_access_uid = *broker_default_value;
401             bpf_map_update_elem(broker_map_ptr, broker_uid_key, broker_default_value, BPF_NOEXIST);
402         }
403     }
404     return network_access_uid;
405 }
406 
filter_sim_stats(__u32 ipv4)407 static inline __u32 filter_sim_stats(__u32 ipv4)
408 {
409     if (IS_MATCHED_IP(ipv4, WLAN_IPv4) || IS_MATCHED_IP(ipv4, CELLULAR_IPv4) || IS_MATCHED_IP(ipv4, CELLULAR_IPv42)) {
410         return 1;
411     }
412     return 0;
413 }
414 
get_iface_type(__u32 ipv4)415 static inline __u32 get_iface_type(__u32 ipv4)
416 {
417     if (IS_MATCHED_IP(ipv4, WLAN_IPv4)) {
418         return IFACE_TYPE_WIFI;
419     }
420     if (IS_MATCHED_IP(ipv4, CELLULAR_IPv4) || IS_MATCHED_IP(ipv4, CELLULAR_IPv42)) {
421         return IFACE_TYPE_CELLULAR;
422     }
423     return 0;
424 }
425 
426 SEC("cgroup_skb/uid/ingress")
bpf_cgroup_skb_uid_ingress(struct __sk_buff * skb)427 int bpf_cgroup_skb_uid_ingress(struct __sk_buff *skb)
428 {
429 #ifdef FEATURE_NET_FIREWALL_ENABLE
430     if (skb == NULL) {
431         return 1;
432     }
433     if (netfirewall_policy_ingress(skb) != SK_PASS) {
434         return SK_DROP;
435     }
436     if (skb->pkt_type == PACKET_LOOPBACK) {
437         return 1;
438     }
439 #else
440     if (skb == NULL || skb->pkt_type == PACKET_LOOPBACK) {
441         return 1;
442     }
443 #endif
444 
445     uint64_t sock_uid = bpf_get_socket_uid(skb);
446     sock_netns_key key_sock_netns1 = sock_uid;
447     sock_netns_value *value_sock_netns1 = bpf_map_lookup_elem(&sock_netns_map, &key_sock_netns1);
448     sock_netns_key key_sock_netns2 = SOCK_COOKIE_ID_NULL;
449     sock_netns_value *value_sock_netns2 = bpf_map_lookup_elem(&sock_netns_map, &key_sock_netns2);
450     uint64_t network_access_uid = sock_uid;
451     if (value_sock_netns1 != NULL && value_sock_netns2 != NULL && *value_sock_netns1 != *value_sock_netns2) {
452         network_access_uid = check_broker_policy(sock_uid);
453     }
454 
455     uid_access_policy_value *netAccessPolicyValue =
456         bpf_map_lookup_elem(&app_uid_access_policy_map, &network_access_uid);
457     if (netAccessPolicyValue != NULL) {
458         net_bear_type_map_value net_bear_mark_type = check_socket_fwmark(skb->mark);
459         if (check_network_policy(net_bear_mark_type, netAccessPolicyValue) == 0) {
460             return 0;
461         }
462     }
463     app_uid_stats_value *value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
464     if (value == NULL) {
465         app_uid_stats_value newValue = {};
466         bpf_map_update_elem(&app_uid_stats_map, &sock_uid, &newValue, BPF_NOEXIST);
467         value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
468     }
469     if (value != NULL) {
470         __sync_fetch_and_add(&value->rxPackets, 1);
471         __sync_fetch_and_add(&value->rxBytes, skb->len);
472     }
473     socket_cookie_stats_key sock_cookie = bpf_get_socket_cookie(skb);
474     app_cookie_stats_value *value_cookie = bpf_map_lookup_elem(&app_cookie_stats_map, &sock_cookie);
475     if (value_cookie == NULL) {
476         app_cookie_stats_value newValue = {};
477         bpf_map_update_elem(&app_cookie_stats_map, &sock_cookie, &newValue, BPF_NOEXIST);
478         value_cookie = bpf_map_lookup_elem(&app_cookie_stats_map, &sock_cookie);
479     }
480     if (value_cookie != NULL) {
481         __sync_fetch_and_add(&value_cookie->rxPackets, 1);
482         __sync_fetch_and_add(&value_cookie->rxBytes, skb->len);
483     }
484 
485     if (value_sock_netns1 != NULL && value_sock_netns2 != NULL && *value_sock_netns1 == *value_sock_netns2) {
486         app_uid_if_stats_key key = {.uId = sock_uid, .ifIndex = skb->ifindex};
487         app_uid_if_stats_value *value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
488         if (value_uid_if == NULL) {
489             app_uid_if_stats_value newValue = {};
490             bpf_map_update_elem(&app_uid_if_stats_map, &key, &newValue, BPF_NOEXIST);
491             value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
492         }
493         if (value_uid_if != NULL) {
494             __sync_fetch_and_add(&value_uid_if->rxPackets, 1);
495             __sync_fetch_and_add(&value_uid_if->rxBytes, get_data_len(skb));
496         }
497     } else {
498         if (filter_sim_stats(skb->local_ip4) == 1) {
499             app_uid_sim_stats_key key_sim = {.uId = sock_uid, .ifIndex = skb->ifindex,
500                                              .ifType = get_iface_type(skb->local_ip4)};
501             app_uid_sim_stats_value *value_uid_sim = bpf_map_lookup_elem(&app_uid_sim_stats_map, &key_sim);
502             if (value_uid_sim == NULL) {
503                 app_uid_sim_stats_value newValue = {};
504                 bpf_map_update_elem(&app_uid_sim_stats_map, &key_sim, &newValue, BPF_NOEXIST);
505                 value_uid_sim = bpf_map_lookup_elem(&app_uid_sim_stats_map, &key_sim);
506             }
507             if (value_uid_sim != NULL) {
508                 __sync_fetch_and_add(&value_uid_sim->rxPackets, 1);
509                 __sync_fetch_and_add(&value_uid_sim->rxBytes, get_data_len(skb));
510             }
511         }
512     }
513     return 1;
514 }
515 
516 SEC("cgroup_skb/uid/egress")
bpf_cgroup_skb_uid_egress(struct __sk_buff * skb)517 int bpf_cgroup_skb_uid_egress(struct __sk_buff *skb)
518 {
519 #ifdef FEATURE_NET_FIREWALL_ENABLE
520     if (skb == NULL) {
521         return 1;
522     }
523     if (netfirewall_policy_egress(skb) != SK_PASS) {
524         return SK_DROP;
525     }
526     if (skb->pkt_type == PACKET_LOOPBACK) {
527         return 1;
528     }
529 #else
530     if (skb == NULL || skb->pkt_type == PACKET_LOOPBACK) {
531         return 1;
532     }
533 #endif
534 
535     uint64_t sock_uid = bpf_get_socket_uid(skb);
536     sock_netns_key key_sock_netns1 = sock_uid;
537     sock_netns_value *value_sock_netns1 = bpf_map_lookup_elem(&sock_netns_map, &key_sock_netns1);
538     sock_netns_key key_sock_netns2 = SOCK_COOKIE_ID_NULL;
539     sock_netns_value *value_sock_netns2 = bpf_map_lookup_elem(&sock_netns_map, &key_sock_netns2);
540     uint64_t network_access_uid = sock_uid;
541     if (value_sock_netns1 != NULL && value_sock_netns2 != NULL && *value_sock_netns1 != *value_sock_netns2) {
542         network_access_uid = check_broker_policy(sock_uid);
543     }
544     uid_access_policy_value *netAccessPolicyValue =
545         bpf_map_lookup_elem(&app_uid_access_policy_map, &network_access_uid);
546     if (netAccessPolicyValue != NULL) {
547         net_bear_type_map_value net_bear_mark_type = check_socket_fwmark(skb->mark);
548         if (check_network_policy(net_bear_mark_type, netAccessPolicyValue) == 0) {
549             return 0;
550         }
551     }
552 
553     app_uid_stats_value *value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
554     if (value == NULL) {
555         app_uid_stats_value newValue = {};
556         bpf_map_update_elem(&app_uid_stats_map, &sock_uid, &newValue, BPF_NOEXIST);
557         value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
558     }
559     if (value != NULL) {
560         __sync_fetch_and_add(&value->txPackets, 1);
561         __sync_fetch_and_add(&value->txBytes, skb->len);
562     }
563     socket_cookie_stats_key sock_cookie = bpf_get_socket_cookie(skb);
564     app_cookie_stats_value *value_cookie = bpf_map_lookup_elem(&app_cookie_stats_map, &sock_cookie);
565     if (value_cookie == NULL) {
566         app_cookie_stats_value newValue = {};
567         bpf_map_update_elem(&app_cookie_stats_map, &sock_cookie, &newValue, BPF_NOEXIST);
568         value_cookie = bpf_map_lookup_elem(&app_cookie_stats_map, &sock_cookie);
569     }
570     if (value_cookie != NULL) {
571         __sync_fetch_and_add(&value_cookie->txPackets, 1);
572         __sync_fetch_and_add(&value_cookie->txBytes, skb->len);
573     }
574 
575     if (value_sock_netns1 != NULL && value_sock_netns2 != NULL && *value_sock_netns1 == *value_sock_netns2) {
576         app_uid_if_stats_key key = {.uId = sock_uid, .ifIndex = skb->ifindex};
577         app_uid_if_stats_value *value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
578         if (value_uid_if == NULL) {
579             app_uid_if_stats_value newValue = {};
580             bpf_map_update_elem(&app_uid_if_stats_map, &key, &newValue, BPF_NOEXIST);
581             value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
582         }
583         if (value_uid_if != NULL) {
584             __sync_fetch_and_add(&value_uid_if->txPackets, 1);
585             __sync_fetch_and_add(&value_uid_if->txBytes, get_data_len(skb));
586         }
587     } else {
588         if (filter_sim_stats(skb->local_ip4) == 1) {
589             app_uid_sim_stats_key key_sim = {.uId = sock_uid, .ifIndex = skb->ifindex,
590                                              .ifType = get_iface_type(skb->local_ip4)};
591             app_uid_sim_stats_value *value_uid_sim = bpf_map_lookup_elem(&app_uid_sim_stats_map, &key_sim);
592             if (value_uid_sim == NULL) {
593                 app_uid_sim_stats_value newValue = {};
594                 bpf_map_update_elem(&app_uid_sim_stats_map, &key_sim, &newValue, BPF_NOEXIST);
595                 value_uid_sim = bpf_map_lookup_elem(&app_uid_sim_stats_map, &key_sim);
596             }
597             if (value_uid_sim != NULL) {
598                 __sync_fetch_and_add(&value_uid_sim->txPackets, 1);
599                 __sync_fetch_and_add(&value_uid_sim->txBytes, get_data_len(skb));
600             }
601         }
602     }
603     return 1;
604 }
605 // network stats end
606 
607 // internet permission begin
608 bpf_map_def SEC("maps") oh_sock_permission_map = {
609     .type = BPF_MAP_TYPE_HASH,
610     .key_size = sizeof(sock_permission_key),
611     .value_size = sizeof(sock_permission_value),
612     .max_entries = OH_SOCK_PERMISSION_MAP_SIZE,
613 };
614 
615 bpf_map_def SEC("maps") broker_sock_permission_map = {
616     .type = BPF_MAP_TYPE_HASH,
617     .key_size = sizeof(sock_permission_key),
618     .value_size = sizeof(sock_permission_value),
619     .max_entries = BROKER_SOCK_PERMISSION_MAP_SIZE,
620 };
621 
622 SEC("cgroup_sock/inet_create_socket")
inet_create_socket(struct bpf_sock * sk)623 int inet_create_socket(struct bpf_sock *sk)
624 {
625     __u64 uid_gid = bpf_get_current_uid_gid();
626     sock_netns_key key_sock_netns1 = uid_gid & 0x00000000FFFFFFFF;
627     sock_netns_value value_sock_netns1 = bpf_get_netns_cookie(sk);
628     bpf_map_update_elem(&sock_netns_map, &key_sock_netns1, &value_sock_netns1, BPF_NOEXIST);
629     sock_netns_key key_sock_netns2 = SOCK_COOKIE_ID_NULL;
630     sock_netns_value value_sock_netns2 = bpf_get_netns_cookie(NULL);
631     bpf_map_update_elem(&sock_netns_map, &key_sock_netns2, &value_sock_netns2, BPF_NOEXIST);
632 
633     void *map_ptr = &oh_sock_permission_map;
634     if (bpf_get_netns_cookie(sk) != bpf_get_netns_cookie(NULL)) {
635         map_ptr = &broker_sock_permission_map;
636     }
637 
638     __u32 uid = (__u32)(uid_gid & 0x00000000FFFFFFFF);
639     sock_permission_value *value = bpf_map_lookup_elem(map_ptr, &uid);
640     // value == NULL means that the process attached to this uid is not a hap process which started by appspawn
641     // it is a native process, native process should have this permission
642     if (value == NULL) {
643         return 1;
644     }
645     // *value == 0 means no permission
646     if (*value == 0) {
647         return 0;
648     }
649     return 1;
650 }
651 
652 SEC("cgroup_sock/inet_release_socket")
inet_release_socket(struct bpf_sock * sk)653 int inet_release_socket(struct bpf_sock *sk)
654 {
655     sock_netns_key key_sock_netns = bpf_get_socket_cookie(sk);
656     bpf_map_delete_elem(&sock_netns_map, &key_sock_netns);
657 
658     socket_cookie_stats_key key_sock_cookie = bpf_get_socket_cookie(sk);
659     bpf_map_delete_elem(&app_cookie_stats_map, &key_sock_cookie);
660     return 1;
661 }
662 // internet permission end
663 
664 bpf_map_def SEC("maps") ringbuf_map = {
665     .type = BPF_MAP_TYPE_RINGBUF,
666     .max_entries = 256 * 1024 /* 256 KB */,
667 };
668 
socket_check_network_policy(net_bear_type_map_value net_bear_mark_type,net_bear_type_map_value * net_bear_type,uid_access_policy_value * value)669 static inline __u8 socket_check_network_policy(net_bear_type_map_value net_bear_mark_type,
670     net_bear_type_map_value *net_bear_type, uid_access_policy_value *value)
671 {
672     if (((net_bear_mark_type == NETWORK_BEARER_TYPE_WIFI) && (!value->wifiPolicy)) ||
673         ((net_bear_mark_type == NETWORK_BEARER_TYPE_CELLULAR) && (!value->cellularPolicy))) {
674         return 0;
675     } else if (net_bear_mark_type != NETWORK_BEARER_TYPE_INITIAL) {
676         return 1;
677     }
678     if (((*net_bear_type == NETWORK_BEARER_TYPE_WIFI) && (!value->wifiPolicy)) ||
679         ((*net_bear_type == NETWORK_BEARER_TYPE_CELLULAR) && (!value->cellularPolicy))) {
680         return 0;
681     }
682     return 1;
683 }
684 
socket_ringbuf_event_submit(__u32 uid)685 static inline __u8 socket_ringbuf_event_submit(__u32 uid)
686 {
687     uint32_t *e;
688     e = bpf_ringbuf_reserve(&ringbuf_map, sizeof(*e), 0);
689     if (e) {
690         *e = uid;
691         bpf_ringbuf_submit(e, 0);
692         return 1;
693     }
694     return 0;
695 }
696 
697 SEC("cgroup_addr/bind4")
inet_check_bind4(struct bpf_sock_addr * ctx)698 static int inet_check_bind4(struct bpf_sock_addr *ctx)
699 {
700     void *map_ptr = &app_uid_access_policy_map;
701     __u64 uid_gid = bpf_get_current_uid_gid();
702     __u32 uid = (__u32)(uid_gid & 0x00000000FFFFFFFF);
703     if (bpf_get_netns_cookie(ctx) != bpf_get_netns_cookie(NULL)) {
704         uid = check_broker_policy(uid);
705     }
706 
707     uid_access_policy_value *value = bpf_map_lookup_elem(map_ptr, &uid);
708     // value == NULL means that the process attached to this uid is not a hap process which has a default configuration
709     if (value == NULL) {
710         return 1;
711     }
712 
713     void *net_bear_map_ptr = &net_bear_type_map;
714     net_bear_id_key net_bear_id = DEFAULT_NETWORK_BEARER_MAP_KEY;
715     net_bear_type_map_value *net_bear_type = bpf_map_lookup_elem(net_bear_map_ptr, &net_bear_id);
716     if (net_bear_type == NULL) {
717         return 1;
718     }
719 
720     struct bpf_sock *sk = ctx->sk;
721     net_bear_type_map_value net_bear_mark_type = check_socket_fwmark(sk->mark);
722     if (socket_check_network_policy(net_bear_mark_type, net_bear_type, value) == 0) {
723         if (value->diagAckFlag) {
724             return 0;
725         }
726 
727         // the policy configuration needs to be reconfirmed or the network bearer changes
728         if (value->configSetFromFlag) {
729             if (socket_ringbuf_event_submit(uid) != 0) {
730                 value->diagAckFlag = 1;
731             }
732         }
733         value->netIfIndex = *net_bear_type;
734         bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
735         return 0;
736     }
737 
738     value->netIfIndex = *net_bear_type;
739     bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
740     return 1;
741 }
742 
743 SEC("cgroup_addr/bind6")
inet_check_bind6(struct bpf_sock_addr * ctx)744 static int inet_check_bind6(struct bpf_sock_addr *ctx)
745 {
746     void *map_ptr = &app_uid_access_policy_map;
747     __u64 uid_gid = bpf_get_current_uid_gid();
748     __u32 uid = (__u32)(uid_gid & 0x00000000FFFFFFFF);
749     if (bpf_get_netns_cookie(ctx) != bpf_get_netns_cookie(NULL)) {
750         uid = check_broker_policy(uid);
751     }
752 
753     uid_access_policy_value *value = bpf_map_lookup_elem(map_ptr, &uid);
754     // value == NULL means that the process attached to this uid is not a hap process which has a default configuration
755     if (value == NULL) {
756         return 1;
757     }
758 
759     void *net_bear_map_ptr = &net_bear_type_map;
760     net_bear_id_key net_bear_id = DEFAULT_NETWORK_BEARER_MAP_KEY;
761     net_bear_type_map_value *net_bear_type = bpf_map_lookup_elem(net_bear_map_ptr, &net_bear_id);
762     if (net_bear_type == NULL) {
763         return 1;
764     }
765 
766     struct bpf_sock *sk = ctx->sk;
767     net_bear_type_map_value net_bear_mark_type = check_socket_fwmark(sk->mark);
768     if (socket_check_network_policy(net_bear_mark_type, net_bear_type, value) == 0) {
769         if (value->diagAckFlag) {
770             return 0;
771         }
772 
773         // the policy configuration needs to be reconfirmed or the network bearer changes
774         if (value->configSetFromFlag) {
775             if (socket_ringbuf_event_submit(uid) != 0) {
776                 value->diagAckFlag = 1;
777             }
778         }
779         value->netIfIndex = *net_bear_type;
780         bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
781         return 0;
782     }
783 
784     value->netIfIndex = *net_bear_type;
785     bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
786     return 1;
787 }
788 
789 SEC("cgroup_addr/connect4")
inet_check_connect4(struct bpf_sock_addr * ctx)790 static int inet_check_connect4(struct bpf_sock_addr *ctx)
791 {
792     void *map_ptr = &app_uid_access_policy_map;
793     __u64 uid_gid = bpf_get_current_uid_gid();
794     __u32 uid = (__u32)(uid_gid & 0x00000000FFFFFFFF);
795     if (bpf_get_netns_cookie(ctx) != bpf_get_netns_cookie(NULL)) {
796         uid = check_broker_policy(uid);
797     }
798 
799     uid_access_policy_value *value = bpf_map_lookup_elem(map_ptr, &uid);
800     // value == NULL means that the process attached to this uid is not a hap process which has a default configuration
801     if (value == NULL) {
802         return 1;
803     }
804 
805     void *net_bear_map_ptr = &net_bear_type_map;
806     net_bear_id_key net_bear_id = DEFAULT_NETWORK_BEARER_MAP_KEY;
807     net_bear_type_map_value *net_bear_type = bpf_map_lookup_elem(net_bear_map_ptr, &net_bear_id);
808     if (net_bear_type == NULL) {
809         return 1;
810     }
811 
812     struct bpf_sock *sk = ctx->sk;
813     net_bear_type_map_value net_bear_mark_type = check_socket_fwmark(sk->mark);
814     if (socket_check_network_policy(net_bear_mark_type, net_bear_type, value) == 0) {
815         if (value->diagAckFlag) {
816             return 0;
817         }
818 
819         // the policy configuration needs to be reconfirmed or the network bearer changes
820         if (value->configSetFromFlag) {
821             if (socket_ringbuf_event_submit(uid) != 0) {
822                 value->diagAckFlag = 1;
823             }
824         }
825         value->netIfIndex = *net_bear_type;
826         bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
827         return 0;
828     }
829 
830     value->netIfIndex = *net_bear_type;
831     bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
832     return 1;
833 }
834 
835 
836 SEC("cgroup_addr/connect6")
inet_check_connect6(struct bpf_sock_addr * ctx)837 static int inet_check_connect6(struct bpf_sock_addr *ctx)
838 {
839     void *map_ptr = &app_uid_access_policy_map;
840     __u64 uid_gid = bpf_get_current_uid_gid();
841     __u32 uid = (__u32)(uid_gid & 0x00000000FFFFFFFF);
842     if (bpf_get_netns_cookie(ctx) != bpf_get_netns_cookie(NULL)) {
843         uid = check_broker_policy(uid);
844     }
845 
846     uid_access_policy_value *value = bpf_map_lookup_elem(map_ptr, &uid);
847     // value == NULL means that the process attached to this uid is not a hap process which has a default configuration
848     if (value == NULL) {
849         return 1;
850     }
851 
852     void *net_bear_map_ptr = &net_bear_type_map;
853     net_bear_id_key net_bear_id = DEFAULT_NETWORK_BEARER_MAP_KEY;
854     net_bear_type_map_value *net_bear_type = bpf_map_lookup_elem(net_bear_map_ptr, &net_bear_id);
855     if (net_bear_type == NULL) {
856         return 1;
857     }
858 
859     struct bpf_sock *sk = ctx->sk;
860     net_bear_type_map_value net_bear_mark_type = check_socket_fwmark(sk->mark);
861     if (socket_check_network_policy(net_bear_mark_type, net_bear_type, value) == 0) {
862         if (value->diagAckFlag) {
863             return 0;
864         }
865 
866         // the policy configuration needs to be reconfirmed or the network bearer changes
867         if (value->configSetFromFlag) {
868             if (socket_ringbuf_event_submit(uid) != 0) {
869                 value->diagAckFlag = 1;
870             }
871         }
872         value->netIfIndex = *net_bear_type;
873         bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
874         return 0;
875     }
876 
877     value->netIfIndex = *net_bear_type;
878     bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
879     return 1;
880 }
881 
882 SEC("cgroup_addr/sendmsg4")
inet_check_sendmsg4(struct bpf_sock_addr * ctx)883 static int inet_check_sendmsg4(struct bpf_sock_addr *ctx)
884 {
885     void *map_ptr = &app_uid_access_policy_map;
886     __u64 uid_gid = bpf_get_current_uid_gid();
887     __u32 uid = (__u32)(uid_gid & 0x00000000FFFFFFFF);
888     if (bpf_get_netns_cookie(ctx) != bpf_get_netns_cookie(NULL)) {
889         uid = check_broker_policy(uid);
890     }
891 
892     uid_access_policy_value *value = bpf_map_lookup_elem(map_ptr, &uid);
893     // value == NULL means that the process attached to this uid is not a hap process which has a default configuration
894     if (value == NULL) {
895         return 1;
896     }
897 
898     void *net_bear_map_ptr = &net_bear_type_map;
899     net_bear_id_key net_bear_id = DEFAULT_NETWORK_BEARER_MAP_KEY;
900     net_bear_type_map_value *net_bear_type = bpf_map_lookup_elem(net_bear_map_ptr, &net_bear_id);
901     if (net_bear_type == NULL) {
902         return 1;
903     }
904 
905     struct bpf_sock *sk = ctx->sk;
906     net_bear_type_map_value net_bear_mark_type = check_socket_fwmark(sk->mark);
907     if (socket_check_network_policy(net_bear_mark_type, net_bear_type, value) == 0) {
908         if (value->diagAckFlag) {
909             return 0;
910         }
911 
912         // the policy configuration needs to be reconfirmed or the network bearer changes
913         if (value->configSetFromFlag) {
914             if (socket_ringbuf_event_submit(uid) != 0) {
915                 value->diagAckFlag = 1;
916             }
917         }
918         value->netIfIndex = *net_bear_type;
919         bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
920         return 0;
921     }
922 
923     value->netIfIndex = *net_bear_type;
924     bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
925     return 1;
926 }
927 
928 SEC("cgroup_addr/sendmsg6")
inet_check_sendmsg6(struct bpf_sock_addr * ctx)929 static int inet_check_sendmsg6(struct bpf_sock_addr *ctx)
930 {
931     void *map_ptr = &app_uid_access_policy_map;
932     __u64 uid_gid = bpf_get_current_uid_gid();
933     __u32 uid = (__u32)(uid_gid & 0x00000000FFFFFFFF);
934     if (bpf_get_netns_cookie(ctx) != bpf_get_netns_cookie(NULL)) {
935         uid = check_broker_policy(uid);
936     }
937 
938     uid_access_policy_value *value = bpf_map_lookup_elem(map_ptr, &uid);
939     // value == NULL means that the process attached to this uid is not a hap process which has a default configuration
940     if (value == NULL) {
941         return 1;
942     }
943 
944     void *net_bear_map_ptr = &net_bear_type_map;
945     net_bear_id_key net_bear_id = DEFAULT_NETWORK_BEARER_MAP_KEY;
946     net_bear_type_map_value *net_bear_type = bpf_map_lookup_elem(net_bear_map_ptr, &net_bear_id);
947     if (net_bear_type == NULL) {
948         return 1;
949     }
950 
951     struct bpf_sock *sk = ctx->sk;
952     net_bear_type_map_value net_bear_mark_type = check_socket_fwmark(sk->mark);
953     if (socket_check_network_policy(net_bear_mark_type, net_bear_type, value) == 0) {
954         if (value->diagAckFlag) {
955             return 0;
956         }
957 
958         // the policy configuration needs to be reconfirmed or the network bearer changes
959         if (value->configSetFromFlag) {
960             if (socket_ringbuf_event_submit(uid) != 0) {
961                 value->diagAckFlag = 1;
962             }
963         }
964         value->netIfIndex = *net_bear_type;
965         bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
966         return 0;
967     }
968 
969     value->netIfIndex = *net_bear_type;
970     bpf_map_update_elem(map_ptr, &uid, value, BPF_NOEXIST);
971     return 1;
972 }
973 
974 char g_license[] SEC("license") = "GPL";
975