• 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 "dlp_link_file.h"
17 
18 #include <securec.h>
19 #include "dlp_fuse_utils.h"
20 #include "dlp_permission.h"
21 #include "dlp_permission_log.h"
22 #include "fuse_daemon.h"
23 
24 namespace OHOS {
25 namespace Security {
26 namespace DlpPermission {
27 namespace {
28 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpLinkFile"};
29 static const int DEFAULT_INODE_RO_ACCESS = 0440;
30 static const int DEFAULT_INODE_RW_ACCESS = 0640;
31 } // namespace
32 
DlpLinkFile(const std::string & dlpLinkName,const std::shared_ptr<DlpFile> & dlpFile)33 DlpLinkFile::DlpLinkFile(const std::string& dlpLinkName, const std::shared_ptr<DlpFile>& dlpFile)
34     : dlpLinkName_(dlpLinkName), dlpFile_(dlpFile), refcount_(1), stopLinkFlag_(false), hasRead_(false)
35 {
36     (void)memset_s(&fileStat_, sizeof(fileStat_), 0, sizeof(fileStat_));
37     fileStat_.st_ino = static_cast<fuse_ino_t>(reinterpret_cast<uintptr_t>(this));
38     if (dlpFile != nullptr) {
39         uint32_t fileMode =
40             (dlpFile->GetAuthPerm() == DLPFileAccess::READ_ONLY) ? DEFAULT_INODE_RO_ACCESS : DEFAULT_INODE_RW_ACCESS;
41         fileStat_.st_mode = S_IFREG | fileMode;
42     } else {
43         fileStat_.st_mode = 0;
44     }
45     fileStat_.st_nlink = 1;
46     fileStat_.st_uid = getuid();
47     fileStat_.st_gid = getgid();
48 
49     DlpFuseUtils::UpdateCurrTimeStat(&fileStat_.st_atim);
50     DlpFuseUtils::UpdateCurrTimeStat(&fileStat_.st_mtim);
51     DlpFuseUtils::UpdateCurrTimeStat(&fileStat_.st_ctim);
52 }
53 
~DlpLinkFile()54 DlpLinkFile::~DlpLinkFile()
55 {
56 }
57 
SubAndCheckZeroRef(int ref)58 bool DlpLinkFile::SubAndCheckZeroRef(int ref)
59 {
60     if (ref <= 0) {
61         DLP_LOG_WARN(LABEL, "Need sub reference %{public}d is error", ref);
62         return false;
63     }
64     std::lock_guard<std::mutex> lock(refLock_);
65     if (refcount_ < ref) {
66         DLP_LOG_WARN(LABEL, "Need sub reference %{public}d is larger than refcount %{public}d",
67             ref, static_cast<int>(refcount_));
68         return true;
69     }
70     refcount_ -= ref;
71     return (refcount_ <= 0);
72 }
73 
IncreaseRef()74 void DlpLinkFile::IncreaseRef()
75 {
76     std::lock_guard<std::mutex> lock(refLock_);
77     if (refcount_ <= 0) {
78         DLP_LOG_WARN(LABEL, "refcount <= 0, can not increase");
79         return;
80     }
81     refcount_++;
82 }
83 
GetLinkStat()84 struct stat DlpLinkFile::GetLinkStat()
85 {
86     if (dlpFile_ == nullptr) {
87         DLP_LOG_ERROR(LABEL, "Get link file stat fail, dlpFile is null");
88         return fileStat_;
89     }
90 
91     uint64_t res = dlpFile_->GetFsContentSize();
92     if (res != INVALID_FILE_SIZE) {
93         fileStat_.st_size = static_cast<off_t>(res);
94     }
95     return fileStat_;
96 }
97 
Truncate(uint64_t modifySize)98 int32_t DlpLinkFile::Truncate(uint64_t modifySize)
99 {
100     if (stopLinkFlag_) {
101         DLP_LOG_INFO(LABEL, "linkFile is stopping link");
102         return DLP_LINK_FILE_NOT_ALLOW_OPERATE;
103     }
104 
105     if (modifySize >= DLP_MAX_CONTENT_SIZE) {
106         DLP_LOG_ERROR(LABEL, "Truncate fail, modify size %{public}s is invalid", std::to_string(modifySize).c_str());
107         return DLP_FUSE_ERROR_VALUE_INVALID;
108     }
109 
110     if (dlpFile_ == nullptr) {
111         DLP_LOG_ERROR(LABEL, "Truncate link file fail, dlp file is null");
112         return DLP_FUSE_ERROR_DLP_FILE_NULL;
113     }
114     int32_t res = dlpFile_->Truncate(modifySize);
115     if (res < 0) {
116         DLP_LOG_ERROR(LABEL, "Truncate %{public}s file fail, res=%{public}d", std::to_string(modifySize).c_str(), res);
117     } else {
118         DLP_LOG_INFO(LABEL, "Truncate %{public}s in link file succ", std::to_string(modifySize).c_str());
119     }
120     UpdateMtimeStat();
121     return res;
122 }
123 
UpdateAtimeStat()124 void DlpLinkFile::UpdateAtimeStat()
125 {
126     DlpFuseUtils::UpdateCurrTimeStat(&fileStat_.st_atim);
127 }
128 
UpdateMtimeStat()129 void DlpLinkFile::UpdateMtimeStat()
130 {
131     DlpFuseUtils::UpdateCurrTimeStat(&fileStat_.st_mtim);
132 }
133 
Write(uint64_t offset,void * buf,uint32_t size)134 int32_t DlpLinkFile::Write(uint64_t offset, void* buf, uint32_t size)
135 {
136     if (stopLinkFlag_) {
137         DLP_LOG_INFO(LABEL, "linkFile is stopping link");
138         return DLP_LINK_FILE_NOT_ALLOW_OPERATE;
139     }
140 
141     if (dlpFile_ == nullptr) {
142         DLP_LOG_ERROR(LABEL, "Write link file fail, dlp file is null");
143         return DLP_FUSE_ERROR_DLP_FILE_NULL;
144     }
145     int32_t res = dlpFile_->DlpFileWrite(offset, buf, size);
146     if (res < 0) {
147         DLP_LOG_ERROR(LABEL, "Write link file fail, err=%{public}d.", res);
148     }
149     UpdateMtimeStat();
150     return res;
151 }
152 
Read(uint64_t offset,void * buf,uint32_t size,uint32_t uid)153 int32_t DlpLinkFile::Read(uint64_t offset, void* buf, uint32_t size, uint32_t uid)
154 {
155     if (stopLinkFlag_) {
156         DLP_LOG_INFO(LABEL, "linkFile is stopping link");
157         return DLP_LINK_FILE_NOT_ALLOW_OPERATE;
158     }
159 
160     if (dlpFile_ == nullptr) {
161         DLP_LOG_ERROR(LABEL, "Read link file fail, dlp file is null");
162         return DLP_FUSE_ERROR_DLP_FILE_NULL;
163     }
164     UpdateAtimeStat();
165     int32_t res = dlpFile_->DlpFileRead(offset, buf, size, hasRead_, uid);
166     if (res < 0) {
167         DLP_LOG_ERROR(LABEL, "Read link file failed, res %{public}d.", res);
168     }
169     return res;
170 }
171 }  // namespace DlpPermission
172 }  // namespace Security
173 }  // namespace OHOS
174