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