• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #ifndef NETMANAGER_EXT_BPF_NET_FIREWALL_H
17 #define NETMANAGER_EXT_BPF_NET_FIREWALL_H
18 
19 #include <netdb.h>
20 #include <string>
21 #include <thread>
22 #include <unordered_map>
23 #include <chrono>
24 #include <functional>
25 
26 #include "bitmap_manager.h"
27 #include "bpf_mapper.h"
28 #include "i_netfirewall_callback.h"
29 #include "netfirewall/netfirewall_def.h"
30 #include "netfirewall_parcel.h"
31 #include "system_ability.h"
32 #include "system_ability_load_callback_stub.h"
33 
34 namespace OHOS::NetManagerStandard {
35 // Only used for unittest code currently
36 static constexpr const char *FIREWALL_BPF_PATH = "/system/etc/bpf/netsys.o";
37 
38 static constexpr const int CONNTRACK_GC_INTTERVAL_MS = 60000;
39 static constexpr const int RING_BUFFER_POLL_TIME_OUT_MS = -1;
40 
41 static constexpr const char *LOOP_BACK_IPV4 = "127.0.0.0";
42 static constexpr const int LOOP_BACK_IPV4_PREFIXLEN = 8;
43 static constexpr const char *LOOP_BACK_IPV6 = "::1";
44 static constexpr const int LOOP_BACK_IPV6_PREFIXLEN = 128;
45 // convert ebpf types from unix style style to CPP's
46 using Ip4Key = ip4_key;
47 using Ip6Key = ip6_key;
48 using Ipv4LpmKey = struct ipv4_lpm_key;
49 using Ipv6LpmKey = struct ipv6_lpm_key;
50 using PortKey = port_key;
51 using ProtoKey = proto_key;
52 using AppUidKey = appuid_key;
53 using DefaultActionKey = default_action_key;
54 using CurrentUserIdKey = current_user_id_key;
55 using ActionKey = action_key;
56 using ActionValue = action_val;
57 using RuleCode = struct bitmap;
58 using StreamDir = enum stream_dir;
59 using EventType = enum event_type;
60 using Event = struct event;
61 using InterceptEvent = struct intercept_event;
62 using DebugEvent = struct debug_event;
63 using TupleEvent = struct match_tuple;
64 using DebugType = enum debug_type;
65 
66 using CtKey = struct ct_tuple;
67 using CtVaule = struct ct_entry;
68 
69 using DomainHashKey = struct domain_hash_key;
70 using DomainValue = domain_value;
71 using LoopbackValue = loop_back_val;
72 
73 struct NetAddrInfo {
74     uint32_t aiFamily;
75     union {
76         struct in_addr sin;
77         struct in6_addr sin6;
78     } aiAddr;
79 };
80 
81 /**
82  * @brief Callback impl for LoadSystemAbility
83  */
84 class OnDemandLoadManagerCallback : public SystemAbilityLoadCallbackStub {
85 public:
86     /**
87      * called when load SA success
88      *
89      * @param systemAbilityId id of SA which was loaded
90      * @param remoteObject poniter of IRemoteObject
91      */
92     void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject) override;
93 
94     /**
95      * called when load SA fail
96      *
97      * @param systemAbilityId id of SA which was loaded
98      */
99     void OnLoadSystemAbilityFail(int32_t systemAbilityId) override;
100 };
101 
102 /**
103  * Class for setup bpf maps and poll event from bpf ring buffer
104  */
105 class NetsysBpfNetFirewall : public NoCopyable {
106 public:
107     static std::shared_ptr<NetsysBpfNetFirewall> GetInstance();
108 
109     /**
110      * start to listen bpf ring buffer
111      *
112      * @return 0 if success or -1 if an error occurred
113      */
114     int32_t StartListener();
115 
116     /* *
117      * @brief stop listen bpf ring buffer
118      *
119      * @return 0 if success or -1 if an error occurred
120      */
121     int32_t StopListener();
122 
123     /**
124      * Set firewall rules to native
125      *
126      * @param type type of NetFirewallRuleType
127      * @param ruleList list of NetFirewallIpRule
128      * @param isFinish transmit finish or not
129      * @return 0 if success or -1 if an error occurred
130      */
131     int32_t SetFirewallRules(NetFirewallRuleType type, const std::vector<sptr<NetFirewallBaseRule>> &ruleList,
132                              bool isFinish);
133 
134     /**
135      * Set firewall default action
136      *
137      * @param userId user id
138      * @param inDefault  Default action of NetFirewallRuleDirection:RULE_IN
139      * @param outDefault Default action of NetFirewallRuleDirection:RULE_OUT
140      * @return  0 if success or -1 if an error occurred
141      */
142     int32_t SetFirewallDefaultAction(int32_t userId, FirewallRuleAction inDefault, FirewallRuleAction outDefault);
143 
144     /**
145      * Set firewall current user id
146      *
147      * @param userId current user id
148      * @return 0 if success or -1 if an error occurred
149      */
150     int32_t SetFirewallCurrentUserId(int32_t userId);
151 
152     /**
153      * Clear all bpf maps
154      *
155      * @param type type of NetFirewallRuleType
156      * @return  0 if success or -1 if an error occurred
157      */
158     int32_t ClearFirewallRules(NetFirewallRuleType type);
159 
160     /**
161      * Register callback for recevie intercept event
162      *
163      * @param callback implement of INetFirewallCallback
164      * @return 0 if success or -1 if an error occurred
165      */
166     int32_t RegisterCallback(const sptr<NetsysNative::INetFirewallCallback> &callback);
167 
168     /**
169      * Unregister callback for recevie intercept event
170      *
171      * @param callback register callback for recevie intercept event
172      * @return 0 if success or -1 if an error occurred
173      */
174     int32_t UnregisterCallback(const sptr<NetsysNative::INetFirewallCallback> &callback);
175 
176     /**
177      * Load SA on demand
178      *
179      * @param systemAbilityId id of SA want to load
180      * @return 0 if success or -1 if an error occurred
181      */
182     int32_t LoadSystemAbility(int32_t systemAbilityId);
183 
184     /**
185      * Set bpf prog load state
186      *
187      * @param load true if load success or false if an error occurred
188      */
189     void SetBpfLoaded(bool load);
190 
191     /**
192      * Get bpf prog load state
193      */
IsBpfLoaded()194     bool IsBpfLoaded()
195     {
196         return isBpfLoaded_;
197     }
198 
199     void AddDomainCache(const NetAddrInfo &addrInfo);
200     void ClearDomainCache();
201 
202     /**
203      * clear firewall default action
204      *
205      */
206     void ClearFirewallDefaultAction();
207 
208 private:
ClearBpfMap(const char * path,const Key & key,Value & val)209     template <typename Key, typename Value> int ClearBpfMap(const char *path, const Key &key, Value &val)
210     {
211         (void)key;
212         (void)val;
213         BpfMapper<Key, Value> rdMap(path, BPF_F_RDONLY);
214         if (!rdMap.IsValid()) {
215             return -1;
216         }
217         std::vector<Key> keys = rdMap.GetAllKeys();
218         if (keys.empty()) {
219             return 0;
220         }
221         BpfMapper<Key, Value> wrMap(path, BPF_F_WRONLY);
222         if (!wrMap.IsValid()) {
223             NETNATIVE_LOGE("ClearBpfMap: wrMap is invalid");
224             return -1;
225         }
226         if (wrMap.Clear(keys) != 0) {
227             NETNATIVE_LOGE("ClearBpfMap: clear failed");
228             return -1;
229         }
230 
231         return 0;
232     }
233 
WriteBpfMap(const char * path,const Key & key,Value & val)234     template <typename Key, typename Value> int WriteBpfMap(const char *path, const Key &key, Value &val)
235     {
236         BpfMapper<Key, Value> map(path, BPF_F_WRONLY);
237         if (!map.IsValid()) {
238             NETNATIVE_LOGE("WriteBpfMap: map invalid: %{public}s", path);
239             return -1;
240         }
241 
242         if (map.Write(key, val, BPF_ANY) != 0) {
243             NETNATIVE_LOGE("WriteBpfMap: map write failed");
244             return -1;
245         }
246 
247         return 0;
248     }
249 
250     NetsysBpfNetFirewall();
251 
252     static void StartConntrackGcThread(void);
253 
254     static void RingBufferListenThread(void);
255 
256     void StopConntrackGc();
257 
258     static int HandleEvent(void *ctx, void *data, size_t len);
259 
260     static void HandleTupleEvent(TupleEvent *ev);
261 
262     static void HandleInterceptEvent(InterceptEvent *ev);
263 
264     static void HandleDebugEvent(DebugEvent *ev);
265 
266     bool ShouldSkipNotify(sptr<InterceptRecord> record);
267 
268     void NotifyInterceptEvent(InterceptEvent *info);
269 
270     static void ConntrackGcTask();
271 
272     void ClearBpfFirewallRules(NetFirewallRuleDirection direction);
273 
274     void WriteSrcIpv4BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
275 
276     void WriteSrcIpv6BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
277 
278     void WriteDstIpv4BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
279 
280     void WriteDstIpv6BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
281 
282     void WriteSrcPortBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
283 
284     void WriteDstPortBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
285 
286     void WriteProtoBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
287 
288     void WriteAppUidBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
289 
290     void WriteUidBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
291 
292     void WriteActionBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction);
293 
294     int32_t SetBpfFirewallRules(const std::vector<sptr<NetFirewallIpRule>> &ruleList,
295         NetFirewallRuleDirection direction);
296 
297     int32_t SetFirewallIpRules(const std::vector<sptr<NetFirewallIpRule>> &ruleList);
298 
299     int32_t SetFirewallDomainRules(const std::vector<sptr<NetFirewallDomainRule>> &ruleList);
300 
301     void GetDomainHashKey(const std::string &domain, DomainHashKey &out);
302 
303     int32_t SetBpfFirewallDomainRules(FirewallRuleAction action, DomainHashKey &key, DomainValue value,
304         bool isWildcard);
305 
306     void ClearDomainRules();
307 
308     int32_t WriteLoopBackBpfMap();
309 
310     static std::shared_ptr<NetsysBpfNetFirewall> instance_;
311     static bool isBpfLoaded_;
312     static bool keepListen_;
313     std::unique_ptr<std::thread> thread_;
314     std::vector<sptr<NetsysNative::INetFirewallCallback>> callbacks_;
315     sptr<InterceptRecord> oldRecord_ = nullptr;
316     static bool keepGc_;
317     std::unique_ptr<std::thread> gcThread_;
318     static std::unique_ptr<BpfMapper<CtKey, CtVaule>> ctRdMap_, ctWrMap_;
319     std::vector<sptr<NetFirewallIpRule>> firewallIpRules_;
320     std::vector<sptr<NetFirewallDomainRule>> firewallDomainRules_;
321 };
322 } // namespace OHOS::NetManagerStandard
323 #endif /* NETMANAGER_EXT_BPF_NET_FIREWALL_H */
324