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 "fileaccessservicebaseproxy_fuzzer.h"
17
18 #include <string>
19
20 #include "app_file_access_ext_connection.h"
21 #include "file_access_observer_stub.h"
22 #include "file_access_service_client.h"
23
24 #include "accesstoken_kit.h"
25 #include "file_access_helper.h"
26 #include "iservice_registry.h"
27 #include "token_setproc.h"
28 #include "nativetoken_kit.h"
29
30 namespace OHOS {
31 using namespace std;
32 using namespace FileAccessFwk;
33
34 const int ABILITY_ID = 5003;
35 shared_ptr<FileAccessHelper> g_fah = nullptr;
36 const int UID_TRANSFORM_TMP = 20000000;
37 const int UID_DEFAULT = 0;
38
39 template <class T>
TypeCast(const uint8_t * data,int * pos=nullptr)40 T TypeCast(const uint8_t *data, int *pos = nullptr)
41 {
42 if (pos) {
43 *pos += sizeof(T);
44 }
45 return *(reinterpret_cast<const T *>(data));
46 }
47
SetNativeToken()48 void SetNativeToken()
49 {
50 uint64_t tokenId;
51 const char *perms[] = {
52 "ohos.permission.FILE_ACCESS_MANAGER",
53 "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED",
54 "ohos.permission.CONNECT_FILE_ACCESS_EXTENSION"
55 };
56 NativeTokenInfoParams infoInstance = {
57 .dcapsNum = 0,
58 .permsNum = 3,
59 .aclsNum = 0,
60 .dcaps = nullptr,
61 .perms = perms,
62 .acls = nullptr,
63 .aplStr = "system_core",
64 };
65
66 infoInstance.processName = "SetUpTestCase";
67 tokenId = GetAccessTokenId(&infoInstance);
68 const uint64_t systemAppMask = (static_cast<uint64_t>(1) << 32);
69 tokenId |= systemAppMask;
70 SetSelfTokenID(tokenId);
71 OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
72 }
73
GetFileAccessHelper()74 shared_ptr<FileAccessHelper> GetFileAccessHelper()
75 {
76 if (g_fah != nullptr) {
77 return g_fah;
78 }
79 SetNativeToken();
80 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
81 if (saManager == nullptr) {
82 return nullptr;
83 }
84 auto remoteObj = saManager->GetSystemAbility(ABILITY_ID);
85 AAFwk::Want want;
86 vector<AAFwk::Want> wantVec;
87 setuid(UID_TRANSFORM_TMP);
88 int ret = FileAccessHelper::GetRegisteredFileAccessExtAbilityInfo(wantVec);
89 if (ret != OHOS::FileAccessFwk::ERR_OK) {
90 printf("GetRegisteredFileAccessExtAbilityInfo failed.");
91 return nullptr;
92 }
93 bool sus = false;
94 for (size_t i = 0; i < wantVec.size(); i++) {
95 auto element = wantVec[i].GetElement();
96 if (element.GetBundleName() == "com.ohos.UserFile.ExternalFileManager" &&
97 element.GetAbilityName() == "FileExtensionAbility") {
98 want = wantVec[i];
99 sus = true;
100 break;
101 }
102 }
103 if (!sus) {
104 printf("not found bundleName.");
105 return nullptr;
106 }
107 vector<AAFwk::Want> wants {want};
108 g_fah = FileAccessHelper::Creator(remoteObj, wants);
109 setuid(UID_DEFAULT);
110 if (g_fah == nullptr) {
111 printf("creator fileAccessHelper return nullptr.");
112 return nullptr;
113 }
114 return g_fah;
115 }
116
117 class TestObserver : public FileAccessObserverStub {
118 public:
TestObserver()119 TestObserver() {};
120 virtual ~TestObserver() = default;
121 int OnChange(const NotifyMessage ¬ifyMessage) override;
122 };
123
OnChange(const NotifyMessage & notifyMessage)124 int TestObserver::OnChange(const NotifyMessage ¬ifyMessage)
125 {
126 return 1;
127 }
128
OnChangeFuzzTest(sptr<IFileAccessServiceBase> proxy,const uint8_t * data,size_t size)129 bool OnChangeFuzzTest(sptr<IFileAccessServiceBase> proxy, const uint8_t* data, size_t size)
130 {
131 if (data == nullptr || size < sizeof(NotifyType)) {
132 return true;
133 }
134
135 int pos = 0;
136 NotifyType notifyType = TypeCast<NotifyType>(data, &pos);
137 Uri uri(string(reinterpret_cast<const char *>(data + pos), size - pos));
138 proxy->OnChange(uri, notifyType);
139 return true;
140 }
141
ConnectFileExtAbilityFuzzTest(sptr<IFileAccessServiceBase> proxy,const uint8_t * data,size_t size)142 bool ConnectFileExtAbilityFuzzTest(sptr<IFileAccessServiceBase> proxy, const uint8_t* data, size_t size)
143 {
144 int len = size / 2;
145 string bundleName(reinterpret_cast<const char *>(data), len);
146 string infoName(reinterpret_cast<const char *>(data + len), len);
147 AAFwk::Want want;
148 want.SetElementName(bundleName, infoName);
149
150 auto helper = GetFileAccessHelper();
151 if (helper == nullptr) {
152 printf("helper is nullptr.");
153 return 0;
154 }
155 auto connectInfo = helper->GetConnectInfo("com.ohos.UserFile.ExternalFileManager");
156 if (connectInfo == nullptr) {
157 printf("connectInfo is nullptr");
158 return 0;
159 }
160 auto fileAccessExtConnection = connectInfo->fileAccessExtConnection;
161 if (fileAccessExtConnection == nullptr) {
162 printf("fileAccessExtConnection is nullptr");
163 }
164 proxy->ConnectFileExtAbility(want, connectInfo->fileAccessExtConnection);
165 proxy->DisConnectFileExtAbility(connectInfo->fileAccessExtConnection);
166 return true;
167 }
168
UnregisterNotifyNoObserverFuzzTest(sptr<IFileAccessServiceBase> proxy,const uint8_t * data,size_t size)169 bool UnregisterNotifyNoObserverFuzzTest(sptr<IFileAccessServiceBase> proxy, const uint8_t* data, size_t size)
170 {
171 if (data == nullptr || size < sizeof(bool) || g_fah == nullptr) {
172 return true;
173 }
174
175 int pos = sizeof(bool);
176 Uri uri(string(reinterpret_cast<const char *>(data + pos), size - pos));
177 AAFwk::Want want;
178 want.SetElementName(EXTERNAL_BNUDLE_NAME, "FileExtensionAbility");
179 sptr<ConnectExtensionInfo> info = sptr(new (std::nothrow) ConnectExtensionInfo(want, g_fah->token_));
180 proxy->UnregisterNotifyNoObserver(uri, *info);
181 return true;
182 }
183 }
184
185 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)186 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
187 {
188 auto proxy = OHOS::FileAccessFwk::FileAccessServiceClient::GetInstance();
189 if (proxy == nullptr) {
190 printf("service proxy is nullptr");
191 return 0;
192 }
193 /* Run your code on data */
194 OHOS::OnChangeFuzzTest(proxy, data, size);
195 OHOS::ConnectFileExtAbilityFuzzTest(proxy, data, size);
196 OHOS::UnregisterNotifyNoObserverFuzzTest(proxy, data, size);
197 return 0;
198 }
199