2020-11-26 04:43:20 -05:00
|
|
|
#include "process.h"
|
|
|
|
|
|
|
|
#include "stdlib.h"
|
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
enum KernelMQ_Process_Error KernelMQ_Process_List_init(
|
2020-11-26 05:37:53 -05:00
|
|
|
KernelMQ_Process_List *const process_list,
|
|
|
|
const struct KernelMQ_Info *const kinfo
|
2020-11-26 04:43:20 -05:00
|
|
|
) {
|
|
|
|
kmemset(process_list, 0, sizeof(*process_list));
|
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
const enum KernelMQ_Process_Error create_kernel_process_result =
|
2020-11-26 06:56:28 -05:00
|
|
|
KernelMQ_Process_create_from_kernel(&(*process_list)[0], kinfo);
|
2020-11-26 05:37:53 -05:00
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
if (create_kernel_process_result != KERNELMQ_PROCESS_ERROR_OK) {
|
2020-11-26 05:37:53 -05:00
|
|
|
kmemset(process_list, 0, sizeof(*process_list));
|
|
|
|
return create_kernel_process_result;
|
|
|
|
}
|
|
|
|
|
2020-11-26 06:41:04 -05:00
|
|
|
const unsigned int modules_length = kinfo->modules_count;
|
|
|
|
|
|
|
|
if (modules_length > KERNELMQ_PROCESS_LIST_LENGTH - 1) {
|
|
|
|
kmemset(process_list, 0, sizeof(*process_list));
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_MODULES_TOO_MANY;
|
2020-11-26 06:41:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned int mod_index = 0; mod_index < modules_length; ++mod_index) {
|
2020-11-26 07:07:08 -05:00
|
|
|
const enum KernelMQ_Process_Error create_mod_process_result =
|
2020-11-26 06:56:28 -05:00
|
|
|
KernelMQ_Process_create_from_module(
|
2020-11-26 06:41:04 -05:00
|
|
|
&(*process_list)[mod_index + 1],
|
2020-11-26 07:01:38 -05:00
|
|
|
&kinfo->modules[mod_index]
|
2020-11-26 06:41:04 -05:00
|
|
|
);
|
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
if (create_mod_process_result != KERNELMQ_PROCESS_ERROR_OK) {
|
2020-11-26 06:41:04 -05:00
|
|
|
kmemset(process_list, 0, sizeof(*process_list));
|
|
|
|
return create_mod_process_result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_OK;
|
2020-11-26 05:37:53 -05:00
|
|
|
}
|
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
enum KernelMQ_Process_Error KernelMQ_Process_create_from_kernel(
|
2020-11-26 05:37:53 -05:00
|
|
|
struct KernelMQ_Process *const process,
|
|
|
|
const struct KernelMQ_Info *const kinfo
|
|
|
|
) {
|
|
|
|
process->is_present = 1;
|
|
|
|
process->created_from = KERNELMQ_PROCESS_CREATED_FROM_KERNEL;
|
|
|
|
|
2020-11-26 06:41:04 -05:00
|
|
|
const unsigned int cmdline_slen = kstrlen(kinfo->cmdline);
|
2020-11-26 05:37:53 -05:00
|
|
|
|
2020-11-26 06:41:04 -05:00
|
|
|
if (cmdline_slen > KERNELMQ_PROCESS_CMDLINE_SLEN_MAX) {
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_CMDLINE_TOO_LONG;
|
2020-11-26 05:37:53 -05:00
|
|
|
}
|
|
|
|
|
2020-11-26 06:41:04 -05:00
|
|
|
kstrncpy(process->cmdline, kinfo->cmdline, cmdline_slen);
|
2020-11-26 05:37:53 -05:00
|
|
|
|
|
|
|
if (kinfo->areas_count > KERNELMQ_PROCESS_AREAS_LENGTH_MAX) {
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_KERNEL_AREAS_LENGTH_TOO_LONG;
|
2020-11-26 05:37:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const unsigned int areas_length = kinfo->areas_count;
|
|
|
|
|
|
|
|
process->areas_length = areas_length;
|
|
|
|
|
|
|
|
for (unsigned int area_index = 0; area_index < areas_length; ++area_index) {
|
|
|
|
const unsigned long long base = kinfo->areas[area_index].base;
|
|
|
|
const unsigned long long size = kinfo->areas[area_index].size;
|
|
|
|
const unsigned long long limit = kinfo->areas[area_index].limit;
|
|
|
|
|
|
|
|
if (base > 0xFFFFFFFF || size > 0xFFFFFFFF || limit > 0xFFFFFFFF) {
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_ADDR_TOO_BIG;
|
2020-11-26 05:37:53 -05:00
|
|
|
}
|
|
|
|
|
2020-11-26 07:22:33 -05:00
|
|
|
if (base + size - 1 != limit) {
|
|
|
|
return KERNELMQ_PROCESS_ERROR_INVALID_AREA;
|
|
|
|
}
|
|
|
|
|
2020-11-26 05:37:53 -05:00
|
|
|
process->areas[area_index].base = base;
|
|
|
|
process->areas[area_index].size = size;
|
|
|
|
process->areas[area_index].limit = limit;
|
|
|
|
}
|
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_OK;
|
2020-11-26 04:43:20 -05:00
|
|
|
}
|
2020-11-26 06:41:04 -05:00
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
enum KernelMQ_Process_Error KernelMQ_Process_create_from_module(
|
2020-11-26 06:41:04 -05:00
|
|
|
struct KernelMQ_Process *const process,
|
2020-11-26 07:01:38 -05:00
|
|
|
const struct KernelMQ_Info_Module *const kinfo_module
|
2020-11-26 06:41:04 -05:00
|
|
|
) {
|
|
|
|
process->is_present = 1;
|
|
|
|
process->created_from = KERNELMQ_PROCESS_CREATED_FROM_MODULE;
|
|
|
|
|
2020-11-26 07:01:38 -05:00
|
|
|
const unsigned int cmdline_slen = kstrlen(kinfo_module->cmdline);
|
2020-11-26 06:41:04 -05:00
|
|
|
|
|
|
|
if (cmdline_slen > KERNELMQ_PROCESS_CMDLINE_SLEN_MAX) {
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_CMDLINE_TOO_LONG;
|
2020-11-26 06:41:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
kstrncpy(
|
|
|
|
process->cmdline,
|
2020-11-26 07:01:38 -05:00
|
|
|
kinfo_module->cmdline,
|
2020-11-26 06:41:04 -05:00
|
|
|
cmdline_slen
|
|
|
|
);
|
|
|
|
|
|
|
|
process->areas_length = 1;
|
|
|
|
|
2020-11-26 07:01:38 -05:00
|
|
|
const unsigned long long base = kinfo_module->base;
|
|
|
|
const unsigned long long size = kinfo_module->size;
|
|
|
|
const unsigned long long limit = kinfo_module->limit;
|
2020-11-26 06:41:04 -05:00
|
|
|
|
|
|
|
if (base > 0xFFFFFFFF || size > 0xFFFFFFFF || limit > 0xFFFFFFFF) {
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_ADDR_TOO_BIG;
|
2020-11-26 06:41:04 -05:00
|
|
|
}
|
|
|
|
|
2020-11-26 07:22:33 -05:00
|
|
|
if (base + size - 1 != limit) {
|
|
|
|
return KERNELMQ_PROCESS_ERROR_INVALID_AREA;
|
|
|
|
}
|
|
|
|
|
2020-11-26 06:41:04 -05:00
|
|
|
process->areas[0].base = base;
|
|
|
|
process->areas[0].size = size;
|
|
|
|
process->areas[0].limit = limit;
|
|
|
|
|
2020-11-26 07:07:08 -05:00
|
|
|
return KERNELMQ_PROCESS_ERROR_OK;
|
2020-11-26 06:41:04 -05:00
|
|
|
}
|