13f4cbf05Sopenharmony_ci/*
23f4cbf05Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License.
53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at
63f4cbf05Sopenharmony_ci *
73f4cbf05Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83f4cbf05Sopenharmony_ci *
93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and
133f4cbf05Sopenharmony_ci * limitations under the License.
143f4cbf05Sopenharmony_ci */
153f4cbf05Sopenharmony_ci
163f4cbf05Sopenharmony_ci#include "thread_fuzzer.h"
173f4cbf05Sopenharmony_ci#include "fuzz_log.h"
183f4cbf05Sopenharmony_ci#include <iostream>
193f4cbf05Sopenharmony_ci#include <cstdio>
203f4cbf05Sopenharmony_ci#include <ctime>
213f4cbf05Sopenharmony_ci#include <unistd.h>
223f4cbf05Sopenharmony_ci#include <sys/prctl.h>
233f4cbf05Sopenharmony_ci#include <sys/resource.h>
243f4cbf05Sopenharmony_ci#include "fuzzer/FuzzedDataProvider.h"
253f4cbf05Sopenharmony_ci#include "thread_ex.h"
263f4cbf05Sopenharmony_ci
273f4cbf05Sopenharmony_ciusing namespace std;
283f4cbf05Sopenharmony_ci
293f4cbf05Sopenharmony_cinamespace OHOS {
303f4cbf05Sopenharmony_ciconst std::string& DEFAULT_THREAD_NAME = "default";
313f4cbf05Sopenharmony_ciconst int MAX_STACK_SIZE = 1024;
323f4cbf05Sopenharmony_ciconst int MAX_PRIORITY = 10;
333f4cbf05Sopenharmony_ciusing ThreadRunFunc = bool (*)(int& data);
343f4cbf05Sopenharmony_ci
353f4cbf05Sopenharmony_cibool TestRun(int &data)
363f4cbf05Sopenharmony_ci{
373f4cbf05Sopenharmony_ci    sleep(1);
383f4cbf05Sopenharmony_ci    ++data;
393f4cbf05Sopenharmony_ci    return false;
403f4cbf05Sopenharmony_ci}
413f4cbf05Sopenharmony_ci
423f4cbf05Sopenharmony_ciclass TestThread : public OHOS::Thread {
433f4cbf05Sopenharmony_cipublic:
443f4cbf05Sopenharmony_ci    TestThread(const int data, const bool readyToWork, int priority, ThreadRunFunc runFunc)
453f4cbf05Sopenharmony_ci        : data_(data), priority_(priority), name_(DEFAULT_THREAD_NAME), readyToWork_(readyToWork), runFunc_(runFunc)
463f4cbf05Sopenharmony_ci        {};
473f4cbf05Sopenharmony_ci
483f4cbf05Sopenharmony_ci    TestThread() = delete;
493f4cbf05Sopenharmony_ci    ~TestThread() {}
503f4cbf05Sopenharmony_ci
513f4cbf05Sopenharmony_ci    bool ReadyToWork() override;
523f4cbf05Sopenharmony_ci
533f4cbf05Sopenharmony_ci    int data_;
543f4cbf05Sopenharmony_ci    int priority_;
553f4cbf05Sopenharmony_ci    std::string name_;
563f4cbf05Sopenharmony_ciprotected:
573f4cbf05Sopenharmony_ci    bool Run() override;
583f4cbf05Sopenharmony_ci
593f4cbf05Sopenharmony_ciprivate:
603f4cbf05Sopenharmony_ci    bool readyToWork_;
613f4cbf05Sopenharmony_ci    ThreadRunFunc runFunc_;
623f4cbf05Sopenharmony_ci};
633f4cbf05Sopenharmony_ci
643f4cbf05Sopenharmony_cibool TestThread::ReadyToWork()
653f4cbf05Sopenharmony_ci{
663f4cbf05Sopenharmony_ci    return readyToWork_;
673f4cbf05Sopenharmony_ci}
683f4cbf05Sopenharmony_ci
693f4cbf05Sopenharmony_cibool TestThread::Run()
703f4cbf05Sopenharmony_ci{
713f4cbf05Sopenharmony_ci    priority_ = getpriority(PRIO_PROCESS, 0);
723f4cbf05Sopenharmony_ci    char threadName[MAX_THREAD_NAME_LEN + 1] = {0};
733f4cbf05Sopenharmony_ci    prctl(PR_GET_NAME, threadName, 0, 0);
743f4cbf05Sopenharmony_ci    name_ = threadName;
753f4cbf05Sopenharmony_ci
763f4cbf05Sopenharmony_ci    if (runFunc_ != nullptr) {
773f4cbf05Sopenharmony_ci        return (*runFunc_)(data_);
783f4cbf05Sopenharmony_ci    }
793f4cbf05Sopenharmony_ci
803f4cbf05Sopenharmony_ci    return false;
813f4cbf05Sopenharmony_ci}
823f4cbf05Sopenharmony_ci
833f4cbf05Sopenharmony_civoid ThreadTestFunc(FuzzedDataProvider* dataProvider)
843f4cbf05Sopenharmony_ci{
853f4cbf05Sopenharmony_ci    bool readyToWork = dataProvider->ConsumeBool();
863f4cbf05Sopenharmony_ci    bool priority = dataProvider->ConsumeIntegralInRange(0, MAX_PRIORITY);
873f4cbf05Sopenharmony_ci    auto t = std::make_unique<TestThread>(0, readyToWork, priority, TestRun);
883f4cbf05Sopenharmony_ci
893f4cbf05Sopenharmony_ci    int stacksize = dataProvider->ConsumeIntegralInRange(0, MAX_STACK_SIZE);
903f4cbf05Sopenharmony_ci    string name = dataProvider->ConsumeRandomLengthString(MAX_THREAD_NAME_LEN);
913f4cbf05Sopenharmony_ci    bool newPriority = dataProvider->ConsumeIntegralInRange(0, MAX_PRIORITY);
923f4cbf05Sopenharmony_ci    auto result = t->Start(name, newPriority, stacksize);
933f4cbf05Sopenharmony_ci    if (result != ThreadStatus::OK) {
943f4cbf05Sopenharmony_ci        return;
953f4cbf05Sopenharmony_ci    }
963f4cbf05Sopenharmony_ci    t->ReadyToWork();
973f4cbf05Sopenharmony_ci    t->IsExitPending();
983f4cbf05Sopenharmony_ci    t->IsRunning();
993f4cbf05Sopenharmony_ci    t->NotifyExitSync();
1003f4cbf05Sopenharmony_ci}
1013f4cbf05Sopenharmony_ci
1023f4cbf05Sopenharmony_ci} // namespace OHOS
1033f4cbf05Sopenharmony_ci
1043f4cbf05Sopenharmony_ci/* Fuzzer entry point */
1053f4cbf05Sopenharmony_ciextern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
1063f4cbf05Sopenharmony_ci{
1073f4cbf05Sopenharmony_ci    FuzzedDataProvider dataProvider(data, size);
1083f4cbf05Sopenharmony_ci    OHOS::ThreadTestFunc(&dataProvider);
1093f4cbf05Sopenharmony_ci    return 0;
1103f4cbf05Sopenharmony_ci}
111