• 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 #include "dlp_link_manager.h"
16 
17 #include "dlp_file.h"
18 #include "dlp_permission.h"
19 #include "dlp_permission_log.h"
20 #include "fuse_daemon.h"
21 
22 namespace OHOS {
23 namespace Security {
24 namespace DlpPermission {
25 namespace {
26 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpLinkManager"};
27 static const int MAX_FILE_NAME_LEN = 256;
28 static constexpr uint32_t MAX_DLP_LINK_SIZE = 1000; // max open link file
29 }
30 
DlpLinkManager()31 DlpLinkManager::DlpLinkManager()
32 {
33     FuseDaemon::InitFuseFs(FUSE_DEV_FD);
34 }
35 
IsLinkNameValid(const std::string & linkName)36 static bool IsLinkNameValid(const std::string& linkName)
37 {
38     size_t size = linkName.size();
39     return !(size == 0 || size > MAX_FILE_NAME_LEN);
40 }
41 
AddDlpLinkFile(std::shared_ptr<DlpFile> & filePtr,const std::string & dlpLinkName)42 int32_t DlpLinkManager::AddDlpLinkFile(std::shared_ptr<DlpFile>& filePtr, const std::string& dlpLinkName)
43 {
44     if (filePtr == nullptr) {
45         DLP_LOG_ERROR(LABEL, "Add link file fail, dlp file is null");
46         return DLP_FUSE_ERROR_DLP_FILE_NULL;
47     }
48     if (!IsLinkNameValid(dlpLinkName)) {
49         DLP_LOG_ERROR(LABEL, "Add link file fail, link file name %{public}s invalid", dlpLinkName.c_str());
50         return DLP_FUSE_ERROR_VALUE_INVALID;
51     }
52 
53     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(g_DlpLinkMapLock_);
54     if (g_DlpLinkFileNameMap_.size() >= MAX_DLP_LINK_SIZE) {
55         DLP_LOG_ERROR(LABEL, "Add link file fail, too many links");
56         return DLP_FUSE_ERROR_TOO_MANY_LINK_FILE;
57     }
58 
59     if (g_DlpLinkFileNameMap_.count(dlpLinkName) > 0) {
60         DLP_LOG_ERROR(LABEL, "Add link file fail, link file %{public}s exist", dlpLinkName.c_str());
61         return DLP_FUSE_ERROR_LINKFILE_EXIST;
62     }
63 
64     for (auto iter = g_DlpLinkFileNameMap_.begin(); iter != g_DlpLinkFileNameMap_.end(); iter++) {
65         DlpLinkFile* linkFileNode = iter->second;
66         if ((linkFileNode != nullptr) && (filePtr == linkFileNode->GetDlpFilePtr())) {
67             DLP_LOG_ERROR(LABEL, "Add link file fail, this dlp file already has link file");
68             return DLP_FUSE_ERROR_LINKFILE_EXIST;
69         }
70     }
71 
72     DlpLinkFile *node = new (std::nothrow) DlpLinkFile(dlpLinkName, filePtr);
73     if (node == nullptr) {
74         DLP_LOG_ERROR(LABEL, "Add link file fail, alloc link file %{public}s fail", dlpLinkName.c_str());
75         return DLP_FUSE_ERROR_MEMORY_OPERATE_FAIL;
76     }
77 
78     DLP_LOG_INFO(LABEL, "Add link file succ, file name %{public}s", dlpLinkName.c_str());
79     g_DlpLinkFileNameMap_[dlpLinkName] = node;
80     filePtr->SetLinkStatus();
81     return DLP_OK;
82 }
83 
StopDlpLinkFile(std::shared_ptr<DlpFile> & filePtr)84 int32_t DlpLinkManager::StopDlpLinkFile(std::shared_ptr<DlpFile> &filePtr)
85 {
86     if (filePtr == nullptr) {
87         DLP_LOG_ERROR(LABEL, "Stop link file fail, dlp file is null");
88         return DLP_FUSE_ERROR_DLP_FILE_NULL;
89     }
90 
91     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(g_DlpLinkMapLock_);
92     for (auto iter = g_DlpLinkFileNameMap_.begin(); iter != g_DlpLinkFileNameMap_.end(); iter++) {
93         DlpLinkFile* node = iter->second;
94         if (node == nullptr) {
95             DLP_LOG_ERROR(LABEL, "Stop link file fail, file ptr is null");
96             return DLP_FUSE_ERROR_DLP_FILE_NULL;
97         }
98         if (filePtr == node->GetDlpFilePtr()) {
99             node->stopLink();
100             filePtr->RemoveLinkStatus();
101             DLP_LOG_INFO(LABEL, "Stop link file success, file name %{public}s", node->GetLinkName().c_str());
102             return DLP_OK;
103         }
104     }
105     DLP_LOG_ERROR(LABEL, "Stop link file fail, link file not exist");
106     return DLP_FUSE_ERROR_LINKFILE_NOT_EXIST;
107 }
108 
RestartDlpLinkFile(std::shared_ptr<DlpFile> & filePtr)109 int32_t DlpLinkManager::RestartDlpLinkFile(std::shared_ptr<DlpFile> &filePtr)
110 {
111     if (filePtr == nullptr) {
112         DLP_LOG_ERROR(LABEL, "Restart link file fail, dlp file is null");
113         return DLP_FUSE_ERROR_DLP_FILE_NULL;
114     }
115 
116     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(g_DlpLinkMapLock_);
117     for (auto iter = g_DlpLinkFileNameMap_.begin(); iter != g_DlpLinkFileNameMap_.end(); iter++) {
118         DlpLinkFile* node = iter->second;
119         if (node == nullptr) {
120             DLP_LOG_ERROR(LABEL, "Restart link file fail, file ptr is null");
121             return DLP_FUSE_ERROR_DLP_FILE_NULL;
122         }
123         if (filePtr == node->GetDlpFilePtr()) {
124             node->restartLink();
125             filePtr->SetLinkStatus();
126             DLP_LOG_INFO(LABEL, "Restart link file success, file name %{public}s", node->GetLinkName().c_str());
127             return DLP_OK;
128         }
129     }
130     DLP_LOG_ERROR(LABEL, "Restart link file fail, link file not exist");
131     return DLP_FUSE_ERROR_LINKFILE_NOT_EXIST;
132 }
133 
ReplaceDlpLinkFile(std::shared_ptr<DlpFile> & filePtr,const std::string & dlpLinkName)134 int32_t DlpLinkManager::ReplaceDlpLinkFile(std::shared_ptr<DlpFile> &filePtr, const std::string &dlpLinkName)
135 {
136     if (filePtr == nullptr) {
137         DLP_LOG_ERROR(LABEL, "Replace link file fail, dlp file is null");
138         return DLP_FUSE_ERROR_DLP_FILE_NULL;
139     }
140     if (!IsLinkNameValid(dlpLinkName)) {
141         DLP_LOG_ERROR(LABEL, "Replace link file fail, link file name %{public}s invalid", dlpLinkName.c_str());
142         return DLP_FUSE_ERROR_VALUE_INVALID;
143     }
144 
145     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(g_DlpLinkMapLock_);
146     for (auto iter = g_DlpLinkFileNameMap_.begin(); iter != g_DlpLinkFileNameMap_.end(); iter++) {
147         if (dlpLinkName == iter->first) {
148             DlpLinkFile *node = iter->second;
149             if (node == nullptr) {
150                 DLP_LOG_ERROR(
151                     LABEL, "Replace link file fail, file %{public}s found but file ptr is null", dlpLinkName.c_str());
152                 return DLP_FUSE_ERROR_DLP_FILE_NULL;
153             }
154             node->setDlpFilePtr(filePtr);
155             DLP_LOG_INFO(LABEL, "Replace link file success, file name %{public}s", dlpLinkName.c_str());
156             return DLP_OK;
157         }
158     }
159     DLP_LOG_ERROR(LABEL, "Replace link file fail, file %{public}s not exist", dlpLinkName.c_str());
160     return DLP_FUSE_ERROR_LINKFILE_NOT_EXIST;
161 }
162 
DeleteDlpLinkFile(std::shared_ptr<DlpFile> & filePtr)163 int32_t DlpLinkManager::DeleteDlpLinkFile(std::shared_ptr<DlpFile>& filePtr)
164 {
165     if (filePtr == nullptr) {
166         return DLP_FUSE_ERROR_DLP_FILE_NULL;
167     }
168 
169     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(g_DlpLinkMapLock_);
170     for (auto iter = g_DlpLinkFileNameMap_.begin(); iter != g_DlpLinkFileNameMap_.end(); iter++) {
171         DlpLinkFile* tmp = iter->second;
172         if (tmp != nullptr && filePtr == tmp->GetDlpFilePtr()) {
173             filePtr->RemoveLinkStatus();
174             g_DlpLinkFileNameMap_.erase(iter);
175             if (tmp->SubAndCheckZeroRef(1)) {
176                 DLP_LOG_INFO(LABEL, "Delete link file %{private}s ok", tmp->GetLinkName().c_str());
177                 delete tmp;
178             } else {
179                 DLP_LOG_INFO(LABEL, "Link file %{private}s is still referenced by kernel, only remove it from map",
180                     tmp->GetLinkName().c_str());
181             }
182             return DLP_OK;
183         }
184     }
185     DLP_LOG_ERROR(LABEL, "Delete link file fail, it does not exist.");
186     return DLP_FUSE_ERROR_LINKFILE_NOT_EXIST;
187 }
188 
LookUpDlpLinkFile(const std::string & dlpLinkName)189 DlpLinkFile* DlpLinkManager::LookUpDlpLinkFile(const std::string& dlpLinkName)
190 {
191     Utils::UniqueReadGuard<Utils::RWLock> infoGuard(g_DlpLinkMapLock_);
192     for (auto iter = g_DlpLinkFileNameMap_.begin(); iter != g_DlpLinkFileNameMap_.end(); iter++) {
193         if (dlpLinkName == iter->first) {
194             DlpLinkFile* node = iter->second;
195             if (node == nullptr) {
196                 DLP_LOG_ERROR(LABEL, "Look up link file fail, file %{public}s found but file ptr is null",
197                     dlpLinkName.c_str());
198                 return nullptr;
199             }
200             node->IncreaseRef();
201             return node;
202         }
203     }
204     DLP_LOG_ERROR(LABEL, "Look up link file fail, file %{public}s not exist", dlpLinkName.c_str());
205     return nullptr;
206 }
207 
DumpDlpLinkFile(std::vector<DlpLinkFileInfo> & linkList)208 void DlpLinkManager::DumpDlpLinkFile(std::vector<DlpLinkFileInfo>& linkList)
209 {
210     Utils::UniqueReadGuard<Utils::RWLock> infoGuard(g_DlpLinkMapLock_);
211     for (auto iter = g_DlpLinkFileNameMap_.begin(); iter != g_DlpLinkFileNameMap_.end(); iter++) {
212         DlpLinkFile* filePtr = iter->second;
213         if (filePtr == nullptr) {
214             continue;
215         }
216         DlpLinkFileInfo info;
217         info.dlpLinkName = filePtr->GetLinkName();
218         info.fileStat = filePtr->GetLinkStat();
219         linkList.emplace_back(info);
220     }
221 }
222 
GetInstance()223 DlpLinkManager& DlpLinkManager::GetInstance()
224 {
225     static DlpLinkManager instance;
226     return instance;
227 }
228 }  // namespace DlpPermission
229 }  // namespace Security
230 }  // namespace OHOS
231