• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "hook_socket_client.h"
17 
18 #include "common.h"
19 #include "hook_common.h"
20 #include "unix_socket_client.h"
21 #include "logging.h"
22 
23 namespace {
24 const int MOVE_BIT_8 = 8;
25 const int MOVE_BIT_32 = 32;
26 const int MOVE_BIT_48 = 48;
27 const int MOVE_BIT_56 = 56;
28 constexpr int FLUSH_FLAG = 20;
29 int g_flushCount = 0;
30 } // namespace
31 
HookSocketClient(int pid,ClientConfig * config)32 HookSocketClient::HookSocketClient(int pid, ClientConfig *config) : pid_(pid), config_(config)
33 {
34     smbFd_ = 0;
35     eventFd_ = 0;
36     unixSocketClient_ = nullptr;
37     serviceName_ = "HookService";
38     Connect(DEFAULT_UNIX_SOCKET_HOOK_FULL_PATH);
39 }
40 
~HookSocketClient()41 HookSocketClient::~HookSocketClient()
42 {
43     unixSocketClient_ = nullptr;
44     stackWriter_ = nullptr;
45 }
46 
Connect(const std::string addrname)47 bool HookSocketClient::Connect(const std::string addrname)
48 {
49     if (unixSocketClient_ != nullptr) {
50         return false;
51     }
52     unixSocketClient_ = std::make_shared<UnixSocketClient>();
53     if (!unixSocketClient_->Connect(addrname, *this)) {
54         unixSocketClient_ = nullptr;
55         return false;
56     }
57 
58     unixSocketClient_->SendHookConfig(pid_);
59     return true;
60 }
61 
62 // config |F F        F F               F F F F       F F F F      F F F F|
63 //        malloctype  stack depth       filtersize    sharememory  size
ProtocolProc(SocketContext & context,uint32_t pnum,const int8_t * buf,const uint32_t size)64 bool HookSocketClient::ProtocolProc(SocketContext &context, uint32_t pnum, const int8_t *buf, const uint32_t size)
65 {
66     if (size != sizeof(uint64_t)) {
67         HILOG_ERROR(LOG_CORE, "HookSocketClient::config config size not match = %u\n", size);
68         return true;
69     }
70     uint64_t config = *(uint64_t *)buf;
71     uint32_t smbSize = (uint32_t)config;
72     config_->filterSize_ = (uint16_t)(config >> MOVE_BIT_32);
73 
74     uint16_t mask = (uint16_t)(config >> MOVE_BIT_48);
75     config_->maxStackDepth_ = (uint8_t)(mask >> MOVE_BIT_8);
76     config_->maxStackDepth_  = config_->maxStackDepth_ > MAX_UNWIND_DEPTH ? MAX_UNWIND_DEPTH : config_->maxStackDepth_;
77     smbFd_ = context.ReceiveFileDiscriptor();
78     eventFd_ = context.ReceiveFileDiscriptor();
79 
80     if (mask & MALLOCDISABLE) {
81         config_->mallocDisable_ = true;
82     }
83     if (mask & MMAPDISABLE) {
84         config_->mmapDisable_ = true;
85     }
86     if (mask & FREEMSGSTACK) {
87         config_->freeStackData_ = true;
88     }
89     if (mask & MUNMAPMSGSTACK) {
90         config_->munmapStackData_ = true;
91     }
92     if (mask & FPUNWIND) {
93         config_->fpunwind_ = true;
94     }
95     if ((mask & BLOCKED) != 0) {
96         config_->isBlocked = true;
97     }
98     HILOG_INFO(LOG_CORE, "%s: mallocDisable = %d mmapDisable = %d", __func__,
99         config_->mallocDisable_, config_->mmapDisable_);
100     HILOG_INFO(LOG_CORE, "%s: freeStackData = %d munmapStackData = %d", __func__,
101         config_->freeStackData_, config_->munmapStackData_);
102     HILOG_INFO(LOG_CORE, "%s: filter size = %u smb size = %u", __func__, config_->filterSize_, smbSize);
103     HILOG_INFO(LOG_CORE, "%s: maxStackDepth = %u fpunwind = %d isBlocked = %d", __func__, config_->maxStackDepth_,
104                config_->fpunwind_, config_->isBlocked);
105     stackWriter_ = std::make_shared<StackWriter>("hooknativesmb", smbSize, smbFd_, eventFd_, config_->isBlocked);
106 
107     COMMON::PrintMallinfoLog("stackWriter init(byte) => ");
108     return true;
109 }
110 
SendStack(const void * data,size_t size)111 bool HookSocketClient::SendStack(const void* data, size_t size)
112 {
113     if (stackWriter_ == nullptr || unixSocketClient_ == nullptr) {
114         return true;
115     }
116 
117     if (!unixSocketClient_->SendHeartBeat()) {
118         return false;
119     }
120 
121     stackWriter_->WriteTimeout(data, size);
122     stackWriter_->Flush();
123 
124     return true;
125 }
126 
SendStackWithPayload(const void * data,size_t size,const void * payload,size_t payloadSize)127 bool HookSocketClient::SendStackWithPayload(const void* data, size_t size, const void* payload, size_t payloadSize)
128 {
129     if (stackWriter_ == nullptr || unixSocketClient_ == nullptr) {
130         return true;
131     }
132 
133     stackWriter_->WriteWithPayloadTimeout(data, size, payload, payloadSize);
134     g_flushCount++;
135     if (g_flushCount % FLUSH_FLAG == 0) {
136         stackWriter_->Flush();
137     }
138     return true;
139 }
140 
Flush()141 void HookSocketClient::Flush()
142 {
143     if (stackWriter_ == nullptr || unixSocketClient_ == nullptr) {
144         return;
145     }
146     stackWriter_->Flush();
147 }
148