add dec test script

Signed-off-by: staralien <chengxin@servicecenter-harmonytsc.com>
This commit is contained in:
staralien
2026-01-29 19:37:20 +08:00
parent 0afc82cd6f
commit adafc22688
8 changed files with 4699 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (c) 2026 Huawei Device Co., Ltd.
cmake_minimum_required(VERSION 3.10)
project(dec_examples)
# compile toolchains
# ./prebuilts/ohos-sdk/linux/${version}/native/build-tools/cmake/bin/cmake \
# -DCMAKE_TOOLCHAIN_FILE=./prebuilts/ohos-sdk/linux/${version}/native/build/cmake/ohos.toolchain.cmake \
# -DOHOS_STL=c++_static \
# -DOHOS_PLATFORM=OHOS \
# -DOHOS_ARCH=armeabi-v7a
#compile dectool
add_executable(dectool
dectool.cpp
dec_test.cpp
token_setproc.cpp
)
File diff suppressed because it is too large Load Diff
+464
View File
@@ -0,0 +1,464 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*/
#include "dec_test.h"
#include "token_setproc.h"
#include <cstdlib>
#include <sys/wait.h>
#include <cstdint>
#include <string>
#include <cstdio>
#include <fcntl.h>
const int32_t DEC_CHAR_LEN = 256;
const int32_t DEC_BUF_LEN = 32;
const int32_t DEC_CNT_LEN = 5;
int g_fd;
bool ExcuteCmd(const std::string& cmd)
{
int result = system(cmd.c_str());
if (result == -1) {
printf("Excute cmd:%s failed\n", cmd.c_str());
return false;
}
if (!WIFEXITED(result)) {
printf("Cmd:%s not exit normal\n", cmd.c_str());
return false;
}
int status = WEXITSTATUS(result);
if (status != 0) {
printf("Cmd:%s return status not ok\n", cmd.c_str());
}
return (status == 0);
}
std::string GetDir(const std::string& fileName)
{
size_t lastSlashPos = fileName.find_last_of("/\\");
if (lastSlashPos == std::string::npos) {
return "";
}
std::string fileDir = fileName.substr(0, lastSlashPos);
return fileDir;
}
int OpenDevDec()
{
if (g_fd == 0) {
g_fd = open("/dev/dec", O_RDWR);
if (g_fd < 0) {
return -1;
}
}
return 0;
}
int GetDecFd()
{
return g_fd;
}
int ConstraintPath(const std::string& path)
{
if (OpenDevDec() != 0) {
return -1;
}
struct dec_rule_s info;
info.addPath(path.c_str());
int ret = ioctl(g_fd, CONSTRAINT_DEC_RULE_CMD, &info);
if (ret != 0) {
printf("constraint path:%s ioctl failed\n", path.c_str());
return -1;
}
if (info.path[0].ret_flag) {
return 0;
}
return -1;
}
int SetPrefix(const std::string& path)
{
struct dec_rule_s info;
info.addPath(path.c_str());
int ret = ioctl(g_fd, SET_DEC_PREFIX_CMD, &info);
if (ret != 0) {
printf("set prefex:%s ioctl failed\n", path.c_str());
return -1;
}
if (info.path[0].ret_flag) {
return 0;
}
return -1;
}
void DecTestClose()
{
if (g_fd > 0) {
close(g_fd);
g_fd = 0;
}
}
int SetProcessId(int32_t uid, int32_t gid)
{
if (uid != 0) {
if (setuid(uid) != 0) {
return -1;
}
}
if (gid != 0) {
if (setgid(gid) != 0) {
return -1;
}
}
return 0;
}
int SetPath(uint64_t tokenid, const std::string& path, uint32_t mode, bool persistFlag,
uint64_t timestamp, int32_t userId)
{
if (OpenDevDec() != 0) {
return -1;
}
struct dec_rule_s info;
info.addPath(path.c_str(), mode);
info.persistFlag = persistFlag;
info.tokenId = tokenid;
info.timeStamp = timestamp;
info.userId = userId;
int ret = ioctl(g_fd, SET_DEC_RULE_CMD, &info);
if (ret != 0) {
return -1;
}
if (info.path[0].ret_flag) {
return 0;
}
return -1;
}
int DenyPath(uint64_t tokenid, const std::string& path, uint32_t mode,
uint64_t timestamp, int32_t userId)
{
if (OpenDevDec() != 0) {
return -1;
}
struct dec_rule_s info;
info.addPath(path.c_str(), mode);
info.tokenId = tokenid;
info.timeStamp = timestamp;
info.userId = userId;
int ret = ioctl(g_fd, DENY_DEC_RULE_CMD, &info);
if (ret != 0) {
return -1;
}
if (info.path[0].ret_flag) {
return 0;
}
return -1;
}
int CheckPath(uint64_t tokenid, const std::string& path, uint32_t mode)
{
if (OpenDevDec() != 0) {
return -1;
}
struct dec_rule_s info;
info.addPath(path.c_str(), mode);
info.tokenId = tokenid;
int ret = ioctl(g_fd, CHECK_DEC_RULE_CMD, &info);
if (ret != 0) {
return -1;
}
if (info.path[0].ret_flag) {
return 0;
}
return -1;
}
int TestWrite(uint64_t tokenid, const std::string& fileName, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
FILE* fp = fopen(fileName.c_str(), "w");
if (fp == NULL) {
printf("TestWrite open failed err:%s\n", strerror(errno));
return -1;
}
const char* str = "Hello";
int ret = fwrite(str, 1, strlen(str), fp);
if (ret < 0) {
fclose(fp);
return -1;
}
if (fclose(fp) != 0) {
return -1;
}
return 0;
}
int TestRead(uint64_t tokenid, const std::string& fileName, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
FILE* fp = fopen(fileName.c_str(), "r");
if (fp == NULL) {
printf("TestRead open failed err:%s\n", strerror(errno));
return -1;
}
char buf[DEC_BUF_LEN];
int ret = fread(buf, 1, sizeof(buf), fp);
if (ret < 0) {
fclose(fp);
return -1;
}
if (fclose(fp) != 0) {
return -1;
}
return 0;
}
int TestCopy(uint64_t tokenid, const std::string& srcPath, const std::string& dstPath, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
std::ifstream in(srcPath, std::ios::binary);
std::ofstream out(dstPath, std::ios::binary);
if (!in || !out) {
return -1;
}
out << in.rdbuf();
in.close();
out.close();
return 0;
}
int Mkdir(uint64_t tokenid, std::string path, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
if (path.empty()) {
return -1;
}
const char lastChar = path.back();
if (lastChar != '\\' && lastChar != '/') {
path.append("/");
}
int len = path.length();
char tmpDirPath[DEC_CHAR_LEN] = { 0 };
int ret = -1;
for (int i = 0; i < len; i++) {
tmpDirPath[i] = path[i];
if (tmpDirPath[i] == '\\' || tmpDirPath[i] == '/') {
if (access(tmpDirPath, 0) == -1) {
ret = mkdir(tmpDirPath, S_IRWXU);
}
}
}
if (ret == -1) {
printf("mkdir failed %s\n", strerror(errno));
return -1;
}
return 0;
}
int TestRename(uint64_t tokenid, const std::string& fileName, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
std::__fs::filesystem::path filePath = fileName;
std::string newName = GetDir(fileName);
newName.append("/new");
newName.append(filePath.filename());
int ret = rename(fileName.c_str(), newName.c_str());
if (ret != 0) {
printf("rename failed err:%s\n", strerror(errno));
return -1;
}
ret = rename(newName.c_str(), fileName.c_str());
if (ret != 0) {
printf("rename back failed err:%s\n", strerror(errno));
return -1;
}
return 0;
}
int TestRename2(uint64_t tokenid, const std::string& fileName, const std::string& targetName, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
int ret = rename(fileName.c_str(), targetName.c_str());
if (ret != 0) {
printf("rename failed err:%s\n", strerror(errno));
return -1;
}
return 0;
}
int TestRemove(uint64_t tokenid, const std::string& fileName, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
int ret = unlink(fileName.c_str());
if (ret != 0) {
printf("remove file:%s failed %s\n", fileName.c_str(), strerror(errno));
return -1;
}
return 0;
}
int DestroyByTokenid(uint64_t tokenid, uint64_t timestamp)
{
if (OpenDevDec() != 0) {
return -1;
}
struct dec_rule_s info;
info.tokenId = tokenid;
info.timeStamp = timestamp;
int ret = ioctl(g_fd, DESTORY_DEC_RULE_CMD, &info);
if (ret != 0) {
return -1;
}
return 0;
}
int QueryPath(uint64_t tokenid, const std::string& path, uint32_t mode)
{
if (OpenDevDec() != 0) {
return -1;
}
struct dec_rule_s info;
info.addPath(path.c_str(), mode);
info.tokenId = tokenid;
int ret = ioctl(g_fd, QUERY_DEC_RULE_CMD, &info);
if (ret != 0) {
return -1;
}
if (info.path[0].ret_flag) {
return 0;
}
return -1;
}
int TestAccess(uint64_t tokenid, const std::string& fileName, uint32_t mode, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
int ret = access(fileName.c_str(), F_OK);
if (ret != 0) {
return -1;
}
if (mode & DEC_MODE_READ) {
ret = access(fileName.c_str(), R_OK);
if (ret != 0) {
return -1;
}
}
if (mode & DEC_MODE_WRITE) {
ret = access(fileName.c_str(), W_OK);
if (ret != 0) {
return -1;
}
}
return 0;
}
int DeletePath(uint64_t tokenid, const std::string& path, uint64_t timestamp)
{
if (OpenDevDec() != 0) {
return -1;
}
struct dec_rule_s info;
info.addPath(path.c_str());
info.tokenId = tokenid;
info.timeStamp = timestamp;
int ret = ioctl(g_fd, DEL_DEC_RULE_CMD, &info);
if (ret != 0) {
return -1;
}
if (info.path[0].ret_flag) {
return 0;
}
return -1;
}
int TestReadDir(uint64_t tokenid, const std::string& dirName, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
DIR* dir;
struct dirent* ent;
if ((dir = opendir(dirName.c_str())) != NULL) {
int cnt = 0;
while ((ent = readdir(dir)) != NULL) {
std::cout << ent->d_name << std::endl;
cnt++;
if (cnt > DEC_CNT_LEN) {
break;
}
}
closedir(dir);
} else {
printf("open dir:%s failed %s\n", dirName.c_str(), strerror(errno));
return -1;
}
return 0;
}
int TestRemoveDir(uint64_t tokenid, const std::string& fileName, int32_t uid, int32_t gid)
{
SetSelfTokenID(tokenid);
if (SetProcessId(uid, gid) != 0) {
return -1;
}
int ret = rmdir(fileName.c_str());
if (ret != 0) {
printf("TestRemoveDir file:%s failed %s\n", fileName.c_str(), strerror(errno));
return -1;
}
return 0;
}
int DeletePathByUser(int32_t user_id, const std::string& path)
{
if (OpenDevDec() != 0) {
return -1;
}
struct dec_rule_s info;
info.addPath(path.c_str());
info.userId = user_id;
int ret = ioctl(g_fd, DEL_DEC_RULE_BY_USER_CMD, &info);
if (ret != 0) {
return -1;
}
if (info.path[0].ret_flag) {
return 0;
}
return -1;
}
+158
View File
@@ -0,0 +1,158 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*/
#ifndef _DEC_TEST_H
#define _DEC_TEST_H
#include <cstdio>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <memory.h>
#include <sys/mount.h>
#include <filesystem>
#include <errno.h>
#include <iostream>
#include <getopt.h>
#include <dirent.h>
#include <sys/vfs.h>
#include <sys/xattr.h>
#define MAX_POLICY_NUM 8
#define DEC_POLICY_HEADER_RESERVED 64
enum ErrorCode {
RET_OK = 0,
RET_FAIL,
};
struct path_info {
char *path;
uint32_t path_len;
uint32_t mode;
bool ret_flag;
path_info() : path(NULL), path_len(0), mode(0), ret_flag(false) {}
path_info(const char *_path) : mode(0)
{
path = (char *)malloc(strlen(_path) + 1);
(void)memcpy(path, _path, strlen(_path));
path_len = strlen(_path);
}
path_info(const char *_path, uint32_t _mode) : mode(_mode)
{
path = (char *)malloc(strlen(_path) + 1);
(void)memcpy(path, _path, strlen(_path));
path_len = strlen(_path);
}
~path_info()
{
if (path != NULL) {
free(path);
path = NULL;
}
}
path_info(const path_info &other)
{
path = (char *)malloc(strlen(other.path) + 1);
(void)memcpy(path, other.path, strlen(other.path));
path_len = other.path_len;
mode = other.mode;
ret_flag = other.ret_flag;
}
path_info &operator=(const path_info &other)
{
path = (char *)malloc(strlen(other.path) + 1);
(void)memcpy(path, other.path, strlen(other.path));
path_len = other.path_len;
mode = other.mode;
ret_flag = other.ret_flag;
return *this;
}
};
struct dec_rule_s {
uint64_t tokenId;
uint64_t timeStamp;
struct path_info path[MAX_POLICY_NUM];
uint32_t pathNum;
int32_t userId;
uint64_t reserved[DEC_POLICY_HEADER_RESERVED];
bool persistFlag;
dec_rule_s() : timeStamp(0), pathNum(0), userId(0), persistFlag(false) {}
void addPath(const char *path_, uint32_t mode_ = 0)
{
struct path_info pathInfo(path_, mode_);
path[pathNum] = pathInfo;
pathNum++;
}
};
#define HM_DEC_IOCTL_BASE 's'
#define HM_SET_POLICY_ID 1
#define HM_DEL_POLICY_ID 2
#define HM_QUERY_POLICY_ID 3
#define HM_CHECK_POLICY_ID 4
#define HM_DESTORY_POLICY_ID 5
#define HM_CONSTRAINT_POLICY_ID 6
#define HM_DEL_POLICY_BY_USER_ID 7
#define HM_SET_PREFIX_ID 8
#define HM_DENY_POLICY_ID 9
#define SET_DEC_RULE_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_SET_POLICY_ID, struct dec_rule_s)
#define DEL_DEC_RULE_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_DEL_POLICY_ID, struct dec_rule_s)
#define QUERY_DEC_RULE_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_QUERY_POLICY_ID, struct dec_rule_s)
#define CHECK_DEC_RULE_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_CHECK_POLICY_ID, struct dec_rule_s)
#define DESTORY_DEC_RULE_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_DESTORY_POLICY_ID, struct dec_rule_s)
#define CONSTRAINT_DEC_RULE_CMD _IOW(HM_DEC_IOCTL_BASE, HM_CONSTRAINT_POLICY_ID, struct dec_rule_s)
#define DEL_DEC_RULE_BY_USER_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_DEL_POLICY_BY_USER_ID, struct dec_rule_s)
#define SET_DEC_PREFIX_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_SET_PREFIX_ID, struct dec_rule_s)
#define DENY_DEC_RULE_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_DENY_POLICY_ID, struct dec_rule_s)
#define DEC_MODE_READ 1
#define DEC_MODE_WRITE 2
#define DEC_MODE_RW 3
#define DEC_CREATE_MODE (1 << 2)
#define DEC_DELETE_MODE (1 << 3)
#define DEC_RENAME_MODE (1 << 4)
#define DEC_DENY_RENAME (1 << 7)
#define DEC_DENY_REMOVE (1 << 8)
#define DEC_DENY_INHERIT (1 << 9)
int OpenDevDec();
int GetDecFd();
bool ExcuteCmd(const std::string &cmd);
int ConstraintPath(const std::string &path);
int SetPrefix(const std::string &path);
int SetPath(uint64_t tokenid, const std::string &path, uint32_t mode, bool persistFlag,
uint64_t timestamp, int32_t userId);
int DenyPath(uint64_t tokenid, const std::string &path, uint32_t mode, uint64_t timestamp, int32_t userId);
int CheckPath(uint64_t tokenid, const std::string &path, uint32_t mode);
int TestWrite(uint64_t tokenid, const std::string &fileName, int32_t uid = 0, int32_t gid = 0);
int TestRead(uint64_t tokenid, const std::string &fileName, int32_t uid = 0, int32_t gid = 0);
int TestCopy(uint64_t tokenid, const std::string &srcPath, const std::string &dstPath,
int32_t uid = 0, int32_t gid = 0);
int Mkdir(uint64_t tokenid, std::string path, int32_t uid = 0, int32_t gid = 0);
int TestRename(uint64_t tokenid, const std::string &fileName, int32_t uid = 0, int32_t gid = 0);
int TestRename2(uint64_t tokenid, const std::string &fileName, const std::string &targetName, int32_t uid = 0, int32_t gid = 0);
int TestRemove(uint64_t tokenid, const std::string &fileName, int32_t uid = 0, int32_t gid = 0);
int DestroyByTokenid(uint64_t tokenid, uint64_t timestamp = 0);
int QueryPath(uint64_t tokenid, const std::string &path, uint32_t mode);
int TestAccess(uint64_t tokenid, const std::string &fileName, uint32_t mode, int32_t uid = 0, int32_t gid = 0);
int DeletePath(uint64_t tokenid, const std::string &path, uint64_t timestamp);
int TestReadDir(uint64_t tokenid, const std::string &dirName, int32_t uid = 0, int32_t gid = 0);
int TestRemoveDir(uint64_t tokenid, const std::string &fileName, int32_t uid = 0, int32_t gid = 0);
int DeletePathByUser(int32_t user_id, const std::string &path);
void DecTestClose();
#endif /* _DEC_TEST_H */
+619
View File
@@ -0,0 +1,619 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*/
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include "dec_test.h"
#include "token_setproc.h"
#define LOG(msg) std::cout << "[dectool][" << __FILE__ << ":" << __LINE__ << "] " << msg << std::endl
#define LOG_ERROR(msg) std::cerr << "[dectool][ERROR][" << __FILE__ << ":" << __LINE__ << "] " << msg << std::endl
struct Command {
std::string cmd;
std::string tokenid;
std::string path;
std::string dstpath;
std::string mode;
std::string userid;
std::string persist;
std::string timestamp;
bool expect;
bool has_expect;
};
uint64_t stringToUint64(const std::string& str)
{
try {
return std::stoull(str, nullptr, 10);
} catch (const std::exception& e) {
LOG_ERROR("Failed to convert string to uint64_t: " << str << ", error: " << e.what());
return 0;
}
}
int32_t stringToInt32(const std::string& str)
{
try {
return std::stoi(str, nullptr, 10);
} catch (const std::exception& e) {
LOG_ERROR("Failed to convert string to int32_t: " << str << ", error: " << e.what());
return 0;
}
}
uint32_t stringToUint32(const std::string& str)
{
try {
return std::stoul(str, nullptr, 0);
} catch (const std::exception& e) {
LOG_ERROR("Failed to convert string to uint32_t: " << str << ", error: " << e.what());
return 0;
}
}
Command parseCommand(int argc, char* argv[])
{
Command cmd;
cmd.expect = false;
cmd.has_expect = false;
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
if (arg == "--cmd") {
cmd.cmd = argv[++i];
} else if (arg == "--tokenid") {
cmd.tokenid = argv[++i];
} else if (arg == "--path") {
cmd.path = argv[++i];
} else if (arg == "--dstpath") {
cmd.dstpath = argv[++i];
} else if (arg == "--mode") {
cmd.mode = argv[++i];
} else if (arg == "--user_id") {
cmd.userid = argv[++i];
} else if (arg == "--persist") {
cmd.persist = argv[++i];
} else if (arg == "--timestamp") {
cmd.timestamp = argv[++i];
} else if (arg == "--expect") {
cmd.has_expect = true;
std::string expect = argv[++i];
cmd.expect = (expect == "true");
}
}
return cmd;
}
int handleRead(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
std::ifstream file(cmd.path.c_str(), std::ios::binary);
if (!file.is_open()) {
LOG_ERROR("Failed to open file for reading: " << cmd.path << ", errno: " << errno << " - " << strerror(errno));
return -1;
}
std::string content((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
file.close();
LOG("Successfully read file: " << cmd.path);
return 0;
}
int handleWrite(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
std::ofstream file(cmd.path.c_str(), std::ios::binary | std::ios::app);
if (!file.is_open()) {
LOG_ERROR("Failed to open file for writing: " << cmd.path << ", errno: " << errno << " - " << strerror(errno));
return -1;
}
file << "Test data written by dectool\n";
file.close();
LOG("Successfully wrote to file: " << cmd.path);
return 0;
}
int handleCreate(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
std::ofstream file(cmd.path.c_str());
if (!file.is_open()) {
LOG_ERROR("Failed to create file: " << cmd.path << ", errno: " << errno << " - " << strerror(errno));
return -1;
}
file.close();
LOG("Successfully created file: " << cmd.path);
return 0;
}
int handleReaddir(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
DIR* dir = opendir(cmd.path.c_str());
if (!dir) {
LOG_ERROR("Failed to open directory: " << cmd.path << ", errno: " << errno << " - " << strerror(errno));
return -1;
}
struct dirent* entry;
int count = 0;
while ((entry = readdir(dir)) != nullptr) {
count++;
}
closedir(dir);
LOG("Successfully read directory: " << cmd.path << ", found " << count << " entries");
return 0;
}
int handleMkdir(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
std::string path = cmd.path;
if(path.empty()) {
printf("path is empty\n");
return -1;
}
const char lastChar = path.back();
if(lastChar != '\\' && lastChar != '/') {
path.append("/");
}
printf("start mkdir %s\n", path.c_str());
int len = path.length();
char tmpDirPath[256] = { 0 };
for (int i = 0; i < len; i++) {
tmpDirPath[i] = path[i];
if (tmpDirPath[i] == '\\' || tmpDirPath[i] == '/') {
printf("tmpDirPath:%s\n", tmpDirPath);
if (access(tmpDirPath, 0) == -1) {
printf("tmpDirPath:%s not exist\n", tmpDirPath);
int ret = mkdir(tmpDirPath, S_IRWXU);
if (ret == -1) {
printf("mkdir failed %s\n", strerror(errno));
return -1;
}
} else {
printf("tmpDirPath:%s exists\n", tmpDirPath);
}
}
}
printf("mkdir success path:%s\n", path.c_str());
return 0;
}
int handleRemove(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
if (std::remove(cmd.path.c_str()) == 0) {
LOG("Successfully removed file: " << cmd.path);
return 0;
}
LOG_ERROR("Failed to remove file: " << cmd.path << ", errno: " << errno << " - " << strerror(errno));
return -1;
}
std::string GetFileDir(const std::string &fileName)
{
size_t lastSlashPos = fileName.find_last_of("/\\");
if (lastSlashPos == std::string::npos) {
printf("cant find file:%s\n", fileName.c_str());
return "";
}
std::string fileDir = fileName.substr(0, lastSlashPos);
return fileDir;
}
int handleCopy(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
std::string srcPath = cmd.path;
std::string dstPath = cmd.dstpath;
printf("copy %s to %s \n", srcPath.c_str(), dstPath.c_str());
std::ifstream in(srcPath, std::ios::binary);
std::ofstream out(dstPath, std::ios::binary);
if (!in) {
std::cerr << "open fail" << std::endl;
return 1;
}
if (!out) {
std::cerr << "open fail" << std::endl;
return 1;
}
out << in.rdbuf();
in.close();
out.close();
std::cout << "copy success" << std::endl;
return 0;
}
int handleRename(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
std::string fileName = cmd.path;
std::__fs::filesystem::path filePath = cmd.path;
std::string newName = GetFileDir(cmd.path);
newName.append("/new");
newName.append(filePath.filename());
printf("fileName:%s newName:%s\n", fileName.c_str(), newName.c_str());
int ret = rename(fileName.c_str(), newName.c_str());
if (ret != 0) {
printf("rename failed err:%s\n", strerror(errno));
return -1;
}
ret = rename(newName.c_str(), fileName.c_str());
if (ret != 0) {
printf("rename back failed err:%s\n", strerror(errno));
return -1;
}
return 0;
LOG_ERROR("Failed to rename " << cmd.path << " to " << cmd.dstpath << ", errno: " << errno << " - " << strerror(errno));
return -1;
}
int handleRename2(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
if (std::rename(cmd.path.c_str(), cmd.dstpath.c_str()) == 0) {
LOG("Successfully renamed " << cmd.path << " to " << cmd.dstpath);
return 0;
}
LOG_ERROR("Failed to rename " << cmd.path << " to " << cmd.dstpath << ", errno: " << errno << " - " << strerror(errno));
return -1;
}
int handleAccess(const Command& cmd)
{
SetSelfTokenID(stringToUint64(cmd.tokenid));
int mode = 0;
if (!cmd.mode.empty()) {
try {
mode = std::stoi(cmd.mode);
} catch (const std::exception& e) {
LOG_ERROR("Invalid mode value: " << cmd.mode << ", error: " << e.what());
return -1;
}
}
int checkMode = 0;
switch (mode) {
case 0: checkMode = F_OK; break;
case 1: checkMode = R_OK; break;
case 2: checkMode = W_OK; break;
case 3: checkMode = R_OK | W_OK; break;
default:
LOG_ERROR("Invalid mode specified: " << mode);
return -1;
}
if (access(cmd.path.c_str(), checkMode) == 0) {
LOG("Access check passed for " << cmd.path << " with mode " << mode);
return 0;
}
LOG_ERROR("Access check failed for " << cmd.path << " with mode " << mode << ", errno: " << errno << " - " << strerror(errno));
return -1;
}
int handleSet(const Command& cmd)
{
if (cmd.tokenid.empty()) {
LOG_ERROR("tokenid is required for set command");
return -1;
}
if (cmd.path.empty()) {
LOG_ERROR("path is required for set command");
return -1;
}
if (cmd.mode.empty()) {
LOG_ERROR("mode is required for set command");
return -1;
}
uint64_t tokenid = stringToUint64(cmd.tokenid);
uint32_t mode = stringToUint32(cmd.mode);
bool persistFlag = false;
if (!cmd.persist.empty()) {
persistFlag = (cmd.persist == "true");
}
uint64_t timestamp = 0;
if (!cmd.timestamp.empty()) {
timestamp = stringToUint64(cmd.timestamp);
}
int32_t userId = 0;
if (!cmd.userid.empty()) {
userId = stringToInt32(cmd.userid);
}
LOG("Calling SetPath: tokenid=" << tokenid << ", path=" << cmd.path
<< ", mode=" << mode << ", persistFlag=" << persistFlag
<< ", timestamp=" << timestamp << ", userId=" << userId);
int result = SetPath(tokenid, cmd.path, mode, persistFlag, timestamp, userId);
LOG("SetPath returned: " << result);
return result;
}
int handleConstraint(const Command& cmd)
{
if (cmd.path.empty()) {
LOG_ERROR("path is required for constraint command");
return -1;
}
LOG("Calling ConstraintPath: path=" << cmd.path);
int result = ConstraintPath(cmd.path);
LOG("ConstraintPath returned: " << result);
return result;
}
int handleCheck(const Command& cmd)
{
if (cmd.tokenid.empty()) {
LOG_ERROR("tokenid is required for check command");
return -1;
}
if (cmd.path.empty()) {
LOG_ERROR("path is required for check command");
return -1;
}
uint64_t tokenid = stringToUint64(cmd.tokenid);
uint32_t mode = 0;
if (!cmd.mode.empty()) {
mode = stringToUint32(cmd.mode);
} else {
LOG_ERROR("mode is required for check command");
return -1;
}
LOG("Calling CheckPath: tokenid=" << tokenid << ", path=" << cmd.path << ", mode=" << mode);
int result = CheckPath(tokenid, cmd.path, mode);
LOG("CheckPath returned: " << result);
return result;
}
int handleQuery(const Command& cmd)
{
if (cmd.tokenid.empty()) {
LOG_ERROR("tokenid is required for query command");
return -1;
}
if (cmd.path.empty()) {
LOG_ERROR("path is required for query command");
return -1;
}
uint64_t tokenid = stringToUint64(cmd.tokenid);
uint32_t mode = 0;
if (!cmd.mode.empty()) {
mode = stringToUint32(cmd.mode);
} else {
LOG_ERROR("mode is required for query command");
return -1;
}
LOG("Calling QueryPath: tokenid=" << tokenid << ", path=" << cmd.path << ", mode=" << mode);
int result = QueryPath(tokenid, cmd.path, mode);
LOG("QueryPath returned: " << result);
return result;
}
int handleDelete(const Command& cmd)
{
if (cmd.tokenid.empty()) {
LOG_ERROR("tokenid is required for delete command");
return -1;
}
if (cmd.path.empty()) {
LOG_ERROR("path is required for delete command");
return -1;
}
uint64_t tokenid = stringToUint64(cmd.tokenid);
uint64_t timestamp = 0;
if (!cmd.timestamp.empty()) {
timestamp = stringToUint64(cmd.timestamp);
}
LOG("Calling DeletePath: tokenid=" << tokenid << ", path=" << cmd.path << ", timestamp=" << timestamp);
int result = DeletePath(tokenid, cmd.path, timestamp);
LOG("DeletePath returned: " << result);
return result;
}
int handleDeleteByUser(const Command& cmd)
{
if (cmd.userid.empty()) {
LOG_ERROR("userid is required for delete_by_user command");
return -1;
}
if (cmd.path.empty()) {
LOG_ERROR("path is required for delete_by_user command");
return -1;
}
int32_t userId = stringToInt32(cmd.userid);
LOG("Calling DeletePathByUser: user_id=" << userId << ", path=" << cmd.path);
int result = DeletePathByUser(userId, cmd.path);
LOG("DeletePathByUser returned: " << result);
return result;
}
int handleDestroy(const Command& cmd)
{
if (cmd.tokenid.empty()) {
LOG_ERROR("tokenid is required for destroy command");
return -1;
}
uint64_t tokenid = stringToUint64(cmd.tokenid);
uint64_t timestamp = 0;
if (!cmd.timestamp.empty()) {
timestamp = stringToUint64(cmd.timestamp);
}
LOG("Calling DestroyByTokenid: tokenid=" << tokenid << ", timestamp=" << timestamp);
int result = DestroyByTokenid(tokenid, timestamp);
LOG("DestroyByTokenid returned: " << result);
return result;
}
int handleForcedPrefix(const Command& cmd)
{
if (cmd.path.empty()) {
LOG_ERROR("path is required for forced_prefix command");
return -1;
}
LOG("Calling SetPrefix: path=" << cmd.path);
int result = SetPrefix(cmd.path);
LOG("SetPrefix returned: " << result);
return result;
}
int main(int argc, char* argv[])
{
LOG("Starting dectool with " << argc << " arguments");
if (argc < 2) {
LOG_ERROR("Usage: " << argv[0] << " --cmd <command> [options]");
return -1;
}
Command cmd = parseCommand(argc, argv);
LOG("Parsed command: cmd=" << cmd.cmd << ", path=" << cmd.path << ", has_expect=" << cmd.has_expect << ", expect=" << cmd.expect);
int result = -1;
LOG("tokenid=" << cmd.tokenid);
uint64_t tokenid = stringToUint64(cmd.tokenid);
OpenDevDec();
if (cmd.cmd == "read") {
result = handleRead(cmd);
} else if (cmd.cmd == "write") {
result = handleWrite(cmd);
} else if (cmd.cmd == "create") {
result = handleCreate(cmd);
} else if (cmd.cmd == "readdir") {
result = handleReaddir(cmd);
} else if (cmd.cmd == "mkdir") {
result = handleMkdir(cmd);
} else if (cmd.cmd == "remove") {
result = handleRemove(cmd);
} else if (cmd.cmd == "rename") {
result = handleRename(cmd);
} else if (cmd.cmd == "rename2") {
if (cmd.dstpath.empty()) {
LOG_ERROR("dstpath is required for rename command");
return -1;
}
result = handleRename2(cmd);
} else if (cmd.cmd == "copy") {
result = handleCopy(cmd);
} else if (cmd.cmd == "access") {
result = handleAccess(cmd);
} else if (cmd.cmd == "set") {
result = handleSet(cmd);
} else if (cmd.cmd == "constraint") {
result = handleConstraint(cmd);
} else if (cmd.cmd == "check") {
result = handleCheck(cmd);
} else if (cmd.cmd == "query") {
result = handleQuery(cmd);
} else if (cmd.cmd == "delete") {
result = handleDelete(cmd);
} else if (cmd.cmd == "delete_by_user") {
result = handleDeleteByUser(cmd);
} else if (cmd.cmd == "destroy") {
result = handleDestroy(cmd);
} else if (cmd.cmd == "forced_prefix") {
result = handleForcedPrefix(cmd);
} else {
LOG_ERROR("Unknown command: " << cmd.cmd);
return -1;
}
LOG("Command '" << cmd.cmd << "' executed with result: " << result);
if (!cmd.has_expect) {
LOG("No expect parameter specified, returning 0");
return 0;
} else {
if (cmd.expect) {
if (result == 0) {
LOG("Command succeeded as expected (expect=true, result=0), returning 0");
return 0;
} else {
LOG_ERROR("Command failed unexpectedly (expect=true, result=" << result << "), returning -1");
return -1;
}
} else {
if (result != 0) {
LOG("Command failed as expected (expect=false, result=" << result << "), returning 0");
return 0;
} else {
LOG_ERROR("Command succeeded unexpectedly (expect=false, result=0), returning -1");
return -1;
}
}
}
}
+28
View File
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*/
#ifndef DEC_SETPROC_COMMON_H
#define DEC_SETPROC_COMMON_H
#define ACCESS_TOKEN_OK 0
#define ACCESS_TOKEN_PARAM_INVALID (-1)
#define ACCESS_TOKEN_OPEN_ERROR (-2)
#define TOKENID_DEVNODE "/dev/access_token_id"
#define ACCESS_TOKEN_ID_IOCTL_BASE 'A'
enum {
GET_TOKEN_ID = 1,
SET_TOKEN_ID,
GET_FTOKEN_ID,
SET_FTOKEN_ID,
ADD_PERMISSIONS,
REMOVE_PERMISSIONS,
GET_PERMISSION,
SET_PERMISSION,
ACCESS_TOKENID_MAX_NR,
};
#endif // DEC_SETPROC_COMMON_H
+86
View File
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*/
#include "token_setproc.h"
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define ACCESS_TOKENID_GET_TOKENID \
_IOR(ACCESS_TOKEN_ID_IOCTL_BASE, GET_TOKEN_ID, uint64_t)
#define ACCESS_TOKENID_SET_TOKENID \
_IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_TOKEN_ID, uint64_t)
#define ACCESS_TOKENID_GET_FTOKENID \
_IOR(ACCESS_TOKEN_ID_IOCTL_BASE, GET_FTOKEN_ID, uint64_t)
#define ACCESS_TOKENID_SET_FTOKENID \
_IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_FTOKEN_ID, uint64_t)
#define INVAL_TOKEN_ID 0x0
#define TOKEN_ID_LOWMASK 0xffffffff
const uint64_t SET_PROC_FD_TAG = 0xD005A01;
uint64_t GetSelfTokenID(void)
{
uint64_t token = INVAL_TOKEN_ID;
int fd = open(TOKENID_DEVNODE, O_RDWR);
if (fd < 0) {
return INVAL_TOKEN_ID;
}
int ret = ioctl(fd, ACCESS_TOKENID_GET_TOKENID, &token);
if (ret) {
return INVAL_TOKEN_ID;
}
return token;
}
int SetSelfTokenID(uint64_t tokenID)
{
int fd = open(TOKENID_DEVNODE, O_RDWR);
if (fd < 0) {
return ACCESS_TOKEN_OPEN_ERROR;
}
int ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, &tokenID);
if (ret) {
return ret;
}
return ACCESS_TOKEN_OK;
}
uint64_t GetFirstCallerTokenID(void)
{
uint64_t token = INVAL_TOKEN_ID;
int fd = open(TOKENID_DEVNODE, O_RDWR);
if (fd < 0) {
return INVAL_TOKEN_ID;
}
int ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, &token);
if (ret) {
return INVAL_TOKEN_ID;
}
return token;
}
int SetFirstCallerTokenID(uint64_t tokenID)
{
int fd = open(TOKENID_DEVNODE, O_RDWR);
if (fd < 0) {
return ACCESS_TOKEN_OPEN_ERROR;
}
int ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, &tokenID);
if (ret) {
return ret;
}
return ACCESS_TOKEN_OK;
}
+17
View File
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
*/
#ifndef _DEC_TOKEN_SETPROC_H
#define _DEC_TOKEN_SETPROC_H
#include <stdint.h>
#include "setproc_common.h"
uint64_t GetSelfTokenID(void);
int SetSelfTokenID(uint64_t tokenID);
uint64_t GetFirstCallerTokenID(void);
int SetFirstCallerTokenID(uint64_t tokenID);
#endif /* _DEC_TOKEN_SETPROC_H */