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