huawei-mrd-kernel/security/kernel_stp/hw_kernel_stp_uploader.c

182 lines
4.6 KiB
C
Raw Normal View History

/*
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2018. All rights reserved.
* Description: the hw_kernel_stp_uploader.c for kernel data uploading through uevent
* Author: sunhongqing <sunhongqing@huawei.com>
* Create: 2018-03-31
*/
#include "hw_kernel_stp_uploader.h"
static const char *TAG = "kernel_stp_uploader";
static struct kobject *g_kernel_stp_kobj;
static struct kset *g_kernel_stp_kset;
static DEFINE_MUTEX(upload_mutex);
struct stp_item_info item_info[] = {
[KCODE] = { STP_ID_KCODE, STP_NAME_KCODE },
[SYSCALL] = { STP_ID_KCODE_SYSCALL, STP_NAME_KCODE_SYSCALL },
[SE_ENFROCING] = { STP_ID_SE_ENFROCING, STP_NAME_SE_ENFROCING },
[SE_HOOK] = { STP_ID_SE_HOOK, STP_NAME_SE_HOOK },
[ROOT_PROCS] = { STP_ID_ROOT_PROCS, STP_NAME_ROOT_PROCS },
[SETIDS] = { STP_ID_SETIDS, STP_NAME_SETIDS },
[EIMA] = { STP_ID_EIMA, STP_NAME_EIMA },
[MOD_SIGN] = { STP_ID_MOD_SIGN, STP_NAME_MOD_SIGN },
[PTRACE] = { STP_ID_PTRACE, STP_NAME_PTRACE },
[HKIP] = { STP_ID_HKIP, STP_NAME_HKIP },
[CFI] = { STP_ID_CFI, STP_NAME_CFI },
[ITRUSTEE] = { STP_ID_ITRUSTEE, STP_NAME_ITRUSTEE },
[DOUBLE_FREE] = { STP_ID_DOUBLE_FREE, STP_NAME_DOUBLE_FREE },
};
struct stp_item_info *get_item_info_by_idx(int idx)
{
if (idx < STP_ITEM_MAX) {
return &item_info[idx];
} else {
return NULL;
}
};
int kernel_stp_uploader_init(void)
{
const char *kernel_stp_kobj_name = "hw_kernel_stp_scanner";
const char *kernel_stp_kset_name = "hw_kernel_stp_kset";
int ret;
do {
g_kernel_stp_kobj = kobject_create_and_add(kernel_stp_kobj_name,
kernel_kobj);
if (g_kernel_stp_kobj == NULL) {
KSTPLogError(TAG, "creat kobject failed");
ret = KSTP_ERRCODE;
break;
}
g_kernel_stp_kset = kset_create_and_add(kernel_stp_kset_name,
NULL, kernel_kobj);
if (g_kernel_stp_kset == NULL) {
KSTPLogError(TAG, "creat kset failed");
ret = KSTP_ERRCODE;
break;
}
g_kernel_stp_kobj->kset = g_kernel_stp_kset;
ret = kobject_uevent(g_kernel_stp_kobj, KOBJ_ADD);
if (ret != 0) {
KSTPLogError(TAG, "kobj_uevent add failed, result is %d", ret);
break;
}
} while (0);
if (ret != 0) {
kernel_stp_uploader_exit();
KSTPLogError(TAG, "kernel stp kobj init failed");
return ret;
}
KSTPLogTrace(TAG, "kernel_stp_kobj_init ok!");
return ret;
}
void kernel_stp_uploader_exit(void)
{
if (g_kernel_stp_kobj != NULL) {
kobject_put(g_kernel_stp_kobj);
g_kernel_stp_kobj = NULL;
}
if (g_kernel_stp_kset != NULL) {
kset_unregister(g_kernel_stp_kset);
g_kernel_stp_kset = NULL;
}
KSTPLogTrace(TAG, "kernel_stp_kobj_deinit ok!");
}
int kernel_stp_upload_parse(struct stp_item result, char *addition_info,
char *upload_info)
{
if (upload_info == NULL) {
KSTPLogError(TAG, "input arguments invalid");
return -EINVAL;
}
if (addition_info == NULL) {
snprintf(upload_info, STP_INFO_MAXLEN, "stpinfo=%u:%u:%u:%u:%s",
result.id, result.status, result.credible,
result.version, result.name);
} else {
snprintf(upload_info, STP_INFO_MAXLEN, "stpinfo=%u:%u:%u:%u:%s:%s",
result.id, result.status, result.credible,
result.version, result.name, addition_info);
}
return 0;
}
/* concatenate kernel_stp data of type int and type char array */
static int kernel_stp_data_adapter(char **uevent_envp, char *result)
{
int index = 0;
if ((uevent_envp == NULL) || (result == NULL)) {
KSTPLogError(TAG, "input arguments invalid");
return -EINVAL;
}
for (index = 0; index < KERNEL_STP_UEVENT_LEN - 1; index++) {
uevent_envp[index] = result;
KSTPLogDebug(TAG, "uevent_envp[%d] is %s",
index, uevent_envp[index]);
}
return 0;
}
int kernel_stp_upload(struct stp_item result, char *addition_info)
{
int ret;
char *upload_info;
char *uevent_envp[KERNEL_STP_UEVENT_LEN] = { NULL };
if (g_kernel_stp_kobj == NULL) {
KSTPLogDebug(TAG, "kernel stp kobj no creat");
return KSTP_ERRCODE;
}
do {
upload_info = kzalloc(STP_INFO_MAXLEN, GFP_KERNEL);
if (upload_info == NULL) {
KSTPLogError(TAG, "failed to alloc upload_info");
return -EINVAL;
}
ret = kernel_stp_upload_parse(result, addition_info, upload_info);
if (ret != 0) {
KSTPLogError(TAG, "data parse failed, ret is %d", ret);
break;
}
ret = kernel_stp_data_adapter(uevent_envp, upload_info);
if (ret != 0) {
KSTPLogError(TAG, "data adpter failed, ret is %d", ret);
break;
}
ret = kobject_uevent_env(g_kernel_stp_kobj, KOBJ_CHANGE,
uevent_envp);
if (ret != 0) {
KSTPLogError(TAG, "kobj upload failed, ret is %d", ret);
break;
}
KSTPLogTrace(TAG, "event upload finished. result: %d", ret);
} while (0);
if (upload_info != NULL) {
kfree(upload_info);
}
return ret;
}