• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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