1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <linux/bpf.h>
17 #include <linux/if_packet.h>
18 #include <stddef.h>
19 #include <stdint.h>
20
21 #include "bpf/bpf_helpers.h"
22 #include "bpf_def.h"
23
24 #define SEC(NAME) __attribute__((section(NAME), used))
25
26 // network stats begin
27 bpf_map_def SEC("maps") iface_stats_map = {
28 .type = BPF_MAP_TYPE_HASH,
29 .key_size = sizeof(uint64_t),
30 .value_size = sizeof(iface_stats_value),
31 .max_entries = IFACE_STATS_MAP_SIZE,
32 .map_flags = 0,
33 .inner_map_idx = 0,
34 .numa_node = 0,
35 };
36
37 bpf_map_def SEC("maps") app_uid_stats_map = {
38 .type = BPF_MAP_TYPE_HASH,
39 .key_size = sizeof(uint64_t),
40 .value_size = sizeof(app_uid_stats_value),
41 .max_entries = APP_STATS_MAP_SIZE,
42 .map_flags = 0,
43 .inner_map_idx = 0,
44 .numa_node = 0,
45 };
46
47 bpf_map_def SEC("maps") app_uid_if_stats_map = {
48 .type = BPF_MAP_TYPE_HASH,
49 .key_size = sizeof(app_uid_if_stats_key),
50 .value_size = sizeof(app_uid_if_stats_value),
51 .max_entries = IFACE_NAME_MAP_SIZE,
52 .map_flags = 0,
53 .inner_map_idx = 0,
54 .numa_node = 0,
55 };
56
57 bpf_map_def SEC("maps") app_cookie_stats_map = {
58 .type = BPF_MAP_TYPE_HASH,
59 .key_size = sizeof(socket_cookie_stats_key),
60 .value_size = sizeof(app_cookie_stats_value),
61 .max_entries = IFACE_NAME_MAP_SIZE,
62 .map_flags = 0,
63 .inner_map_idx = 0,
64 .numa_node = 0,
65 };
66
67 SEC("cgroup_skb/uid/ingress")
bpf_cgroup_skb_uid_ingress(struct __sk_buff * skb)68 int bpf_cgroup_skb_uid_ingress(struct __sk_buff *skb)
69 {
70 if (skb == NULL) {
71 return 1;
72 }
73 if (skb->pkt_type == PACKET_LOOPBACK) {
74 return 1;
75 }
76 uint64_t sock_uid = bpf_get_socket_uid(skb);
77 app_uid_stats_value *value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
78 if (value == NULL) {
79 app_uid_stats_value newValue = {};
80 bpf_map_update_elem(&app_uid_stats_map, &sock_uid, &newValue, BPF_NOEXIST);
81 value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
82 }
83 if (value != NULL) {
84 __sync_fetch_and_add(&value->rxPackets, 1);
85 __sync_fetch_and_add(&value->rxBytes, skb->len);
86 }
87 app_uid_if_stats_key key = {.uId = sock_uid, .ifIndex = skb->ifindex};
88 app_uid_if_stats_value *value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
89 if (value_uid_if == NULL) {
90 app_uid_if_stats_value newValue = {};
91 bpf_map_update_elem(&app_uid_if_stats_map, &key, &newValue, BPF_NOEXIST);
92 value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
93 }
94 if (value_uid_if != NULL) {
95 __sync_fetch_and_add(&value_uid_if->rxPackets, 1);
96 __sync_fetch_and_add(&value_uid_if->rxBytes, skb->len);
97 }
98 uint64_t ifindex = skb->ifindex;
99 iface_stats_value *value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
100 if (value_if == NULL) {
101 iface_stats_value newValue = {};
102 bpf_map_update_elem(&iface_stats_map, &ifindex, &newValue, BPF_NOEXIST);
103 value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
104 }
105 if (value_if != NULL) {
106 __sync_fetch_and_add(&value_if->rxPackets, 1);
107 __sync_fetch_and_add(&value_if->rxBytes, skb->len);
108 }
109
110 socket_cookie_stats_key sock_cookie = bpf_get_socket_cookie(skb);
111 app_cookie_stats_value *value_cookie = bpf_map_lookup_elem(&app_cookie_stats_map, &sock_cookie);
112 if (value_cookie == NULL) {
113 app_cookie_stats_value newValue = {};
114 bpf_map_update_elem(&app_cookie_stats_map, &sock_cookie, &newValue, BPF_NOEXIST);
115 value_cookie = bpf_map_lookup_elem(&app_cookie_stats_map, &sock_cookie);
116 }
117 if (value_cookie != NULL) {
118 __sync_fetch_and_add(&value_cookie->rxPackets, 1);
119 __sync_fetch_and_add(&value_cookie->rxBytes, skb->len);
120 }
121 return 1;
122 }
123
124 SEC("cgroup_skb/uid/egress")
bpf_cgroup_skb_uid_egress(struct __sk_buff * skb)125 int bpf_cgroup_skb_uid_egress(struct __sk_buff *skb)
126 {
127 if (skb == NULL) {
128 return 1;
129 }
130 if (skb->pkt_type == PACKET_LOOPBACK) {
131 return 1;
132 }
133 uint64_t sock_uid = bpf_get_socket_uid(skb);
134 app_uid_stats_value *value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
135 if (value == NULL) {
136 app_uid_stats_value newValue = {};
137 bpf_map_update_elem(&app_uid_stats_map, &sock_uid, &newValue, BPF_NOEXIST);
138 value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
139 }
140 if (value != NULL) {
141 __sync_fetch_and_add(&value->txPackets, 1);
142 __sync_fetch_and_add(&value->txBytes, skb->len);
143 }
144 app_uid_if_stats_key key = {.uId = sock_uid, .ifIndex = skb->ifindex};
145 app_uid_if_stats_value *value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
146 if (value_uid_if == NULL) {
147 app_uid_if_stats_value newValue = {};
148 bpf_map_update_elem(&app_uid_if_stats_map, &key, &newValue, BPF_NOEXIST);
149 value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
150 }
151 if (value_uid_if != NULL) {
152 __sync_fetch_and_add(&value_uid_if->txPackets, 1);
153 __sync_fetch_and_add(&value_uid_if->txBytes, skb->len);
154 }
155 uint64_t ifindex = skb->ifindex;
156 iface_stats_value *value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
157 if (value_if == NULL) {
158 iface_stats_value newValue = {};
159 bpf_map_update_elem(&iface_stats_map, &ifindex, &newValue, BPF_NOEXIST);
160 value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
161 }
162 if (value_if != NULL) {
163 __sync_fetch_and_add(&value_if->txPackets, 1);
164 __sync_fetch_and_add(&value_if->txBytes, skb->len);
165 }
166
167 socket_cookie_stats_key sock_cookie = bpf_get_socket_cookie(skb);
168 app_cookie_stats_value *value_cookie = bpf_map_lookup_elem(&app_cookie_stats_map, &sock_cookie);
169 if (value_cookie == NULL) {
170 app_cookie_stats_value newValue = {};
171 bpf_map_update_elem(&app_cookie_stats_map, &sock_cookie, &newValue, BPF_NOEXIST);
172 value_cookie = bpf_map_lookup_elem(&app_cookie_stats_map, &sock_cookie);
173 }
174 if (value_cookie != NULL) {
175 __sync_fetch_and_add(&value_cookie->txPackets, 1);
176 __sync_fetch_and_add(&value_cookie->txBytes, skb->len);
177 }
178 return 1;
179 }
180 // network stats end
181
182 // internet permission begin
183 bpf_map_def SEC("maps") oh_sock_permission_map = {
184 .type = BPF_MAP_TYPE_HASH,
185 .key_size = sizeof(sock_permission_key),
186 .value_size = sizeof(sock_permission_value),
187 .max_entries = OH_SOCK_PERMISSION_MAP_SIZE,
188 };
189
190 bpf_map_def SEC("maps") broker_sock_permission_map = {
191 .type = BPF_MAP_TYPE_HASH,
192 .key_size = sizeof(sock_permission_key),
193 .value_size = sizeof(sock_permission_value),
194 .max_entries = BROKER_SOCK_PERMISSION_MAP_SIZE,
195 };
196
197 SEC("cgroup_sock/inet_create_socket")
inet_create_socket(struct bpf_sock * sk)198 int inet_create_socket(struct bpf_sock *sk)
199 {
200 void *map_ptr = &oh_sock_permission_map;
201 if (bpf_get_netns_cookie(sk) != bpf_get_netns_cookie(NULL)) {
202 map_ptr = &broker_sock_permission_map;
203 }
204
205 __u64 uid_gid = bpf_get_current_uid_gid();
206 __u32 uid = (__u32)(uid_gid & 0x00000000FFFFFFFF);
207 sock_permission_value *value = bpf_map_lookup_elem(map_ptr, &uid);
208 // value == NULL means that the process attached to this uid is not a hap process which started by appspawn
209 // it is a native process, native process should have this permission
210 if (value == NULL) {
211 return 1;
212 }
213 // *value == 0 means no permission
214 if (*value == 0) {
215 return 0;
216 }
217 return 1;
218 }
219 // internet permission end
220 char g_license[] SEC("license") = "GPL";
221