1 /*
2 * Copyright (c) 2025 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 "xattr_core.h"
17
18 #include <memory>
19 #include <optional>
20 #include <sys/xattr.h>
21
22 #include "file_utils.h"
23 #include "filemgmt_libhilog.h"
24
25 namespace OHOS {
26 namespace FileManagement {
27 namespace ModuleFileIO {
28 using namespace std;
29 constexpr size_t MAX_XATTR_SIZE = 4096;
30
IsIllegalXattr(const char * key,const char * value)31 static bool IsIllegalXattr(const char *key, const char *value)
32 {
33 bool isIllegalKey = strnlen(key, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE;
34 if (isIllegalKey) {
35 HILOGE("Key is too long");
36 }
37 bool isIllegalValue = strnlen(value, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE;
38 if (isIllegalValue) {
39 HILOGE("value is too long");
40 }
41 return isIllegalKey || isIllegalValue;
42 }
43
GetXattrCore(const char * path,const char * key,std::shared_ptr<string> result)44 static int32_t GetXattrCore(const char *path, const char *key, std::shared_ptr<string> result)
45 {
46 ssize_t xAttrSize = getxattr(path, key, nullptr, 0);
47 if (xAttrSize == -1 || xAttrSize == 0) {
48 *result = "";
49 return ERRNO_NOERR;
50 }
51 auto xattrValue = CreateUniquePtr<char[]>(static_cast<long>(xAttrSize) + 1);
52 xAttrSize = getxattr(path, key, xattrValue.get(), static_cast<size_t>(xAttrSize));
53 if (xAttrSize == -1) {
54 return errno;
55 }
56 xattrValue[xAttrSize] = '\0';
57 *result = std::string(xattrValue.get());
58 return ERRNO_NOERR;
59 }
60
DoSetXattr(const string & path,const string & key,const string & value)61 FsResult<void> XattrCore::DoSetXattr(const string &path, const string &key, const string &value)
62 {
63 if (IsIllegalXattr(key.c_str(), value.c_str())) {
64 HILOGE("Invalid xattr value");
65 return FsResult<void>::Error(EINVAL);
66 }
67 if (setxattr(path.c_str(), key.c_str(), value.c_str(), strnlen(value.c_str(), MAX_XATTR_SIZE), 0) < 0) {
68 HILOGE("Setxattr fail, errno is %{public}d", errno);
69 return FsResult<void>::Error(errno);
70 }
71 return FsResult<void>::Success();
72 }
73
DoGetXattr(const string & path,const string & key)74 FsResult<string> XattrCore::DoGetXattr(const string &path, const string &key)
75 {
76 auto result = make_shared<std::string>();
77 int32_t ret = GetXattrCore(path.c_str(), key.c_str(), result);
78 if (ret != ERRNO_NOERR) {
79 HILOGE("Invalid getxattr");
80 return FsResult<string>::Error(ret);
81 }
82 return FsResult<string>::Success(move(*result));
83 }
84
85 } // namespace ModuleFileIO
86 } // namespace FileManagement
87 } // namespace OHOS